diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8cae9cc30..a49d20c77 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,6 +5,34 @@ community.sap_install Release Notes .. contents:: Topics +v1.3.2 +====== + +Release Summary +--------------- + +| Release Date: 2023-09-29 +sap_general_preconfigure: Update to latest SAP documentation for RHEL 9 package libxcrypt-compat +sap_general_preconfigure: Bug fix for directory creation and SELinux Labels +sap_ha_pacemaker_cluster: Bug fix for AWS EC2 Virtual Servers +sap_ha_pacemaker_cluster: Bug fix for Google Cloud Compute Engine VM netmask lock on Virtual IP +sap_ha_pacemaker_cluster: Feature add for improved SAP NetWeaver HA compatibility +sap_ha_pacemaker_cluster: Feature add for ENSA1 compatibility +sap_ha_pacemaker_cluster: Feature add for SAP HA Interface Cluster Connector after cluster init +sap_ha_pacemaker_cluster: Feature add for IBM PowerVM hypervisor +sap_ha_pacemaker_cluster: Feature add for multiple network interfaces with Virtual IP +sap_hana_install: Bug fix for SELinux disable when SLES4SAP +sap_install_media_detect: Feature add for NFS compatibility +sap_install_media_detect: Feature add for idempotency +sap_install_media_detect: Feature add for new file detection after code restructure +sap_install_media_detect: Bug fix for setting SAP Maintenance Planner Stack XML path +sap_storage_setup: Feature add for Multipathing detection +sap_storage_setup: Bug fix for NFS throttle from customer test on MS Azure +sap_storage_setup: Bug fix for packages on SLES and Google Cloud +sap_swpm: Bug fix for RDBMS var name +sap_swpm: Bug fix for SAP HANA Client hdbuserstore connection +sap_swpm: Bug fix for SAP Maintenance Planner Stack XML path + v1.3.1 ====== @@ -47,7 +75,7 @@ Release Summary | Release Date: 2023-04-25 | sap_hana_preconfigure: Some modifications for HANA on RHEL 9 -| sap_ha_pacemaker_cluster: Support for custom stonith resource definitions containing more than one element +| sap_ha_pacemaker_cluster: Compatibility for custom stonith resource definitions containing more than one element | sap_hana_preconfigure: Be more flexible with IBM service and productivity tools diff --git a/galaxy.yml b/galaxy.yml index 9f4417e77..5238b650d 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -10,7 +10,7 @@ namespace: community name: sap_install # The version of the collection. Must be compatible with semantic versioning -version: 1.3.1 +version: 1.3.2 # The path to the Markdown (.md) readme file. This path is relative to the root of the collection readme: README.md diff --git a/playbooks/sample-sap-ha-deployment-hana-2-node-cluster.yml b/playbooks/sample-sap-ha-deployment-hana-2-node-cluster.yml index db15fcb50..46d6166a6 100644 --- a/playbooks/sample-sap-ha-deployment-hana-2-node-cluster.yml +++ b/playbooks/sample-sap-ha-deployment-hana-2-node-cluster.yml @@ -48,10 +48,9 @@ node_role: secondary hana_site: DC02 - sap_hana_vip: - primary: 192.168.1.100 + sap_ha_pacemaker_cluster_vip_hana_primary_ip_address: 192.168.1.100 - ha_cluster_fence_agent_packages: + sap_ha_pacemaker_cluster_fence_agent_packages: - fence-agents-rhevm sap_ha_pacemaker_cluster_stonith_custom: diff --git a/playbooks/sample-sap-nwas-ascs-ers-2-node-cluster.yml b/playbooks/sample-sap-nwas-ascs-ers-2-node-cluster.yml new file mode 100644 index 000000000..0a2d80c35 --- /dev/null +++ b/playbooks/sample-sap-nwas-ascs-ers-2-node-cluster.yml @@ -0,0 +1,82 @@ +--- +# This playbook will +# - install and configure a basic pacemaker cluster +# - configure the SAP NetWeaver ASCS/ERS resource groups with each +# - an instance filesystem +# - the instance resource +# - an instance service VIP + +# To use this playbook in your test environment +# please update the "vars" parameters with values +# corresponding to your individual naming standards +# and infrastructure (e.g. IP definitions matching your network). +# +# NOTE: +# For simplicity the sample password values are plain text. Please make sure to +# apply security measures to any credentials, for instance using ansible-vault +# encryption. + +- name: "Install and Configure a Pacemaker Cluster on 2 NetWeaver ASCS/ERS nodes" + hosts: ascs-node, ers-node + become: true +# any_error_fatal: true + + vars: + ############################################################################ + ### MANDATORY parameter definitions for a NetWeaver ASCS/ERS cluster setup. + ############################################################################ + + ### General minimum pacemaker cluster definitions. + + # Cluster name is optional, the default of the 'ha_cluster' Linux System Role + # would be applied when missing. + # However, for convenience it is defined along with the rest of the mandatory + # parameters in this example. + sap_ha_pacemaker_cluster_cluster_name: ascs-ers-cluster + sap_ha_pacemaker_cluster_hacluster_user_password: my-hacluster-vault-password + + ### NetWeaver specific definitions + sap_ha_pacemaker_cluster_storage_nfs_server: "nfs-server1.example.com:/" + + # Underlying filesystems are derived from the parent "/usr/sap" definition. + sap_ha_pacemaker_cluster_storage_definition: + - name: usr_sap + mountpoint: /usr/sap + nfs_path: /usr/sap + nfs_server: "{{ sap_ha_pacemaker_cluster_storage_nfs_server }}" + + - name: usr_sap_trans + mountpoint: /usr/sap/trans + nfs_path: /usr/sap/trans + nfs_server: "{{ sap_ha_pacemaker_cluster_storage_nfs_server }}" + + - name: sapmnt + mountpoint: /sapmnt + nfs_path: /sapmnt + nfs_server: "{{ sap_ha_pacemaker_cluster_storage_nfs_server }}" + + # SID and Instance Numbers for ASCS and ERS. + sap_ha_pacemaker_cluster_nwas_abap_sid: ABC + sap_ha_pacemaker_cluster_nwas_abap_ascs_instance_nr: "02" + sap_ha_pacemaker_cluster_nwas_abap_ers_instance_nr: "12" + + # Profile name created by the installer, for example: _ASCS_ + sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_instance_name: ABC_ASCS02_ascs-node-ha + sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_start_profile_string: /sapmnt/ABC/profile/ABC_ASCS02_ascs-node-ha + + sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_instance_name: ABC_ERS12_ers-node-ha + sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_start_profile_string: /sapmnt/ABC/profile/ABC_ERS12_ers-node-ha + + # Required to go through the configuration flow for a NetWeaver ASCS/ERS cluster. + sap_ha_pacemaker_cluster_host_type: + - nwas_abap_ascs_ers + + # Virtual IP addresses, one per instance. + # These IPs will switch between the nodes together with the instance. + sap_ha_pacemaker_cluster_vip_nwas_abap_ascs_ip_address: 192.168.10.102 + sap_ha_pacemaker_cluster_vip_nwas_abap_ers_ip_address: 192.168.10.112 + + + roles: + + - name: sap_ha_pacemaker_cluster diff --git a/playbooks/vars/sample-variables-sap-hana-install.yml b/playbooks/vars/sample-variables-sap-hana-install.yml index 0b12e4752..7a0e73a72 100644 --- a/playbooks/vars/sample-variables-sap-hana-install.yml +++ b/playbooks/vars/sample-variables-sap-hana-install.yml @@ -13,7 +13,7 @@ sap_hana_install_master_password: 'NewPass$321' # Instance details sap_hana_install_sid: 'HDB' -sap_hana_install_instance_number: "00" +sap_hana_install_instance_nr: "00" # ----------------------------- Optional parameters ------------------------------ # diff --git a/playbooks/vars/sample-variables-sap-swpm-default-mode-solman-hana-abap-onehost-install.yml b/playbooks/vars/sample-variables-sap-swpm-default-mode-solman-hana-abap-onehost-install.yml index d1d9c10e0..2840f34cb 100644 --- a/playbooks/vars/sample-variables-sap-swpm-default-mode-solman-hana-abap-onehost-install.yml +++ b/playbooks/vars/sample-variables-sap-swpm-default-mode-solman-hana-abap-onehost-install.yml @@ -45,7 +45,7 @@ sap_swpm_cd_export_pt1_path: /software/download_basket/SOLMAN/51054655_1_DIR sap_swpm_cd_export_pt2_path: /software/download_basket/SOLMAN/51054655_2_DIR sap_swpm_cd_language_path: /software/download_basket/SOLMAN/51054655_3_DIR sap_swpm_cd_java_path: /software/download_basket/SOLMAN/51054655_4_DIR -sap_swpm_cd_rdms_path: /software/download_basket/SAPINST/SAP_HANA/51054623 +sap_swpm_cd_rdbms_path: /software/download_basket/SAPINST/SAP_HANA/51054623 # NW Passwords sap_swpm_master_password: "NewPass$321" diff --git a/playbooks/vars/sample-variables-sap-swpm-default-mode-solman-hana-java-onehost-install.yml b/playbooks/vars/sample-variables-sap-swpm-default-mode-solman-hana-java-onehost-install.yml index 6014fe636..7bc9bd3e8 100644 --- a/playbooks/vars/sample-variables-sap-swpm-default-mode-solman-hana-java-onehost-install.yml +++ b/playbooks/vars/sample-variables-sap-swpm-default-mode-solman-hana-java-onehost-install.yml @@ -47,7 +47,7 @@ sap_swpm_cd_export_pt1_path: /software/download_basket/SOLMAN/51054655_1_DIR sap_swpm_cd_export_pt2_path: /software/download_basket/SOLMAN/51054655_2_DIR sap_swpm_cd_language_path: /software/download_basket/SOLMAN/51054655_3_DIR sap_swpm_cd_java_path: /software/download_basket/SOLMAN/51054655_4_DIR -sap_swpm_cd_rdms_path: /software/download_basket/SAPINST/SAP_HANA/51054623 +sap_swpm_cd_rdbms_path: /software/download_basket/SAPINST/SAP_HANA/51054623 # NW Passwords sap_swpm_master_password: "NewPass$321" diff --git a/roles/sap_general_preconfigure/README.md b/roles/sap_general_preconfigure/README.md index 60a120d95..636ba7660 100644 --- a/roles/sap_general_preconfigure/README.md +++ b/roles/sap_general_preconfigure/README.md @@ -237,11 +237,27 @@ Can be useful if you want to implement your own reboot handling.
One of the SELinux states to be set on the system.
+### sap_general_preconfigure_create_directories +- _Type:_ `bool` +- _Default:_ `true` + +Set to `false` if you do not want the SAP directories to be created by the role.
+The SAP directories will always be created if `sap_general_preconfigure_modify_selinux_labels`
+(see below) is set to `true`, no matter how `sap_general_preconfigure_create_directories` is set.
+ +### sap_general_preconfigure_sap_directories +- _Type:_ `list` with elements of type `str` +- _Default:_ + - /usr/sap + +List of SAP directories to be created.
+ ### sap_general_preconfigure_modify_selinux_labels - _Type:_ `bool` - _Default:_ `true` -Set to `false` if you do not want to modify the SELinux labels for the SAP directory `/usr/sap`.
+Set to `false` if you do not want to modify the SELinux labels for the SAP directores set
+in variable `sap_general_preconfigure_sap_directories`.
### sap_general_preconfigure_size_of_tmpfs_gb - _Type:_ `str` diff --git a/roles/sap_general_preconfigure/defaults/main.yml b/roles/sap_general_preconfigure/defaults/main.yml index e5a1829e9..9687a15ac 100644 --- a/roles/sap_general_preconfigure/defaults/main.yml +++ b/roles/sap_general_preconfigure/defaults/main.yml @@ -115,8 +115,18 @@ sap_general_preconfigure_selinux_state: 'permissive' # - permissive # - disabled +sap_general_preconfigure_create_directories: true +# Set to `false` if you do not want the SAP directories to be created by the role. +# The SAP directories will always be created if `sap_general_preconfigure_modify_selinux_labels` +# (see below) is set to `true`, no matter how `sap_general_preconfigure_create_directories` is set. + +sap_general_preconfigure_sap_directories: + - /usr/sap +# List of SAP directories to be created. + sap_general_preconfigure_modify_selinux_labels: true -# Set to `false` if you do not want to modify the SELinux labels for the SAP directory `/usr/sap`. +# Set to `false` if you do not want to modify the SELinux labels for the SAP directores set +# in variable `sap_general_preconfigure_sap_directories`. sap_general_preconfigure_size_of_tmpfs_gb: "{{ ((0.75 * (ansible_memtotal_mb + ansible_swaptotal_mb)) / 1024) | round | int }}" # The size of the tmpfs in GB. The formula used here is mentioned in SAP note 941735. diff --git a/roles/sap_general_preconfigure/meta/argument_specs.yml b/roles/sap_general_preconfigure/meta/argument_specs.yml index ce48ec90d..2d5993d95 100644 --- a/roles/sap_general_preconfigure/meta/argument_specs.yml +++ b/roles/sap_general_preconfigure/meta/argument_specs.yml @@ -240,10 +240,29 @@ argument_specs: required: false type: str + sap_general_preconfigure_create_directories: + default: true + description: + - Set to `false` if you do not want the SAP directories to be created by the role. + - The SAP directories will always be created if `sap_general_preconfigure_modify_selinux_labels` + - (see below) is set to `true`, no matter how `sap_general_preconfigure_create_directories` is set. + required: false + type: bool + + sap_general_preconfigure_sap_directories: + default: + - '/usr/sap' + description: + - List of SAP directories to be created. + required: false + type: list + elements: str + sap_general_preconfigure_modify_selinux_labels: default: true description: - - Set to `false` if you do not want to modify the SELinux labels for the SAP directory `/usr/sap`. + - Set to `false` if you do not want to modify the SELinux labels for the SAP directores set + - in variable `sap_general_preconfigure_sap_directories`. required: false type: bool diff --git a/roles/sap_general_preconfigure/tasks/RedHat/configuration.yml b/roles/sap_general_preconfigure/tasks/RedHat/configuration.yml index df5a48e9b..5893e00a9 100644 --- a/roles/sap_general_preconfigure/tasks/RedHat/configuration.yml +++ b/roles/sap_general_preconfigure/tasks/RedHat/configuration.yml @@ -4,13 +4,35 @@ ansible.builtin.debug: var: __sap_general_preconfigure_sapnotes_versions | difference(['']) -- name: Configure - Create directory '/usr/sap' +- name: Configure - Set directory variables for setting SELinux file contexts + ansible.builtin.set_fact: + sap_general_preconfigure_fact_targets_setypes: "{{ sap_general_preconfigure_fact_targets_setypes | d([]) + + [__sap_general_preconfigure_tmp_dict_target_setype] }}" + loop: "{{ sap_general_preconfigure_sap_directories }}" + loop_control: + loop_var: line_item + vars: + __sap_general_preconfigure_tmp_dict_target_setype: + target: "{{ line_item }}(/.*)?" + setype: 'usr_t' + when: sap_general_preconfigure_modify_selinux_labels + +- name: Configure - Display directory variable + ansible.builtin.debug: + var: sap_general_preconfigure_fact_targets_setypes + when: sap_general_preconfigure_modify_selinux_labels + +- name: Configure - Create directories ansible.builtin.file: - path: '/usr/sap' + path: "{{ line_item }}" state: directory mode: '0755' owner: root group: root + loop: "{{ sap_general_preconfigure_sap_directories }}" + loop_control: + loop_var: line_item + when: sap_general_preconfigure_create_directories or sap_general_preconfigure_modify_selinux_labels - name: Configure - Include configuration actions for required sapnotes ansible.builtin.include_tasks: "sapnote/{{ sap_note_line_item.number }}.yml" diff --git a/roles/sap_general_preconfigure/tasks/RedHat/generic/configure-selinux.yml b/roles/sap_general_preconfigure/tasks/RedHat/generic/configure-selinux.yml index 4e09d3772..19a406c90 100644 --- a/roles/sap_general_preconfigure/tasks/RedHat/generic/configure-selinux.yml +++ b/roles/sap_general_preconfigure/tasks/RedHat/generic/configure-selinux.yml @@ -18,11 +18,15 @@ register: __sap_general_preconfigure_register_selinux_config_type_changed notify: __sap_general_preconfigure_reboot_handler -- name: Determine the current SELinux state - ansible.builtin.command: getenforce - register: __sap_general_preconfigure_register_getenforce - check_mode: no - changed_when: false +# Set a new SELinux mode variable to the SELinux status if 'disabled' or otherwise to +# the value of the 'mode' member ('permissive' or 'enforcing') +- name: SELinux - Set an SELinux mode variable + ansible.builtin.set_fact: + __sap_general_preconfigure_fact_selinux_mode: "{{ (ansible_selinux.status == 'disabled') | ternary(ansible_selinux.status, ansible_selinux.mode) }}" + +- name: SELinux - Display the current SELinux mode or status + ansible.builtin.debug: + var: __sap_general_preconfigure_fact_selinux_mode # Reason for noqa: We need to notify a handler in another role, which is not possible from a handler in the current role - name: SELinux - Set the flag that reboot is needed to apply changes # noqa no-handler @@ -30,14 +34,12 @@ sap_general_preconfigure_fact_reboot_required: true when: __sap_general_preconfigure_register_selinux_config_state_changed.changed or __sap_general_preconfigure_register_selinux_config_type_changed.changed or - __sap_general_preconfigure_register_getenforce.stdout | lower != - sap_general_preconfigure_selinux_state + __sap_general_preconfigure_fact_selinux_mode != sap_general_preconfigure_selinux_state -- name: Call Reboot handler if necessary +- name: SELinux - Call Reboot handler if necessary ansible.builtin.command: /bin/true notify: __sap_general_preconfigure_reboot_handler - when: __sap_general_preconfigure_register_getenforce.stdout | lower != - sap_general_preconfigure_selinux_state + when: __sap_general_preconfigure_fact_selinux_mode != sap_general_preconfigure_selinux_state - name: Set or unset SELinux kernel parameter, RHEL 8 and RHEL 9 when: @@ -96,14 +98,24 @@ ansible.builtin.debug: var: sap_general_preconfigure_fact_reboot_required | d(false) -- name: Configure '/usr/sap' SELinux file labels +- name: SELinux - Warn if the SELinux file contexts cannot be set + ansible.builtin.debug: + msg: "WARN: The SELinux file context cannot be set on an SELinux disabled system!" + when: + - sap_general_preconfigure_modify_selinux_labels + - __sap_general_preconfigure_fact_selinux_mode == 'disabled' + +- name: SELinux - Configure SELinux file contexts ansible.builtin.include_role: name: '{{ sap_general_preconfigure_system_roles_collection }}.selinux' vars: selinux_booleans: - { name: 'selinuxuser_execmod', state: 'on' } selinux_fcontexts: - - { target: '/usr/sap(/.*)?', setype: 'usr_t' } + - "{{ sap_general_preconfigure_fact_targets_setypes }}" selinux_restore_dirs: - - '/usr/sap' - when: sap_general_preconfigure_modify_selinux_labels + - "{{ sap_general_preconfigure_sap_directories }}" + when: + - sap_general_preconfigure_modify_selinux_labels + - sap_general_preconfigure_selinux_state != 'disabled' + - __sap_general_preconfigure_fact_selinux_mode != 'disabled' diff --git a/roles/sap_general_preconfigure/vars/RedHat_9.yml b/roles/sap_general_preconfigure/vars/RedHat_9.yml index 1b025cc48..ca0d473b7 100644 --- a/roles/sap_general_preconfigure/vars/RedHat_9.yml +++ b/roles/sap_general_preconfigure/vars/RedHat_9.yml @@ -62,6 +62,8 @@ __sap_general_preconfigure_packages_x86_64: - hostname # package tuned: no longer part of package group "Core" in RHEL 9, so we have to install it - tuned +# package libxcrypt-compat: needed by sapstartsrv and SAP HANA on RHEL 9: + - libxcrypt-compat __sap_general_preconfigure_packages_ppc64le: - uuidd @@ -74,6 +76,8 @@ __sap_general_preconfigure_packages_ppc64le: - hostname # package tuned: no longer part of package group "Core" in RHEL 9, so we have to install it - tuned +# package libxcrypt-compat: needed by sapstartsrv and SAP HANA on RHEL 9: + - libxcrypt-compat __sap_general_preconfigure_packages_s390x: - uuidd @@ -86,6 +90,8 @@ __sap_general_preconfigure_packages_s390x: - hostname # package tuned: no longer part of package group "Core" in RHEL 9, so we have to install it - tuned +# package libxcrypt-compat: needed by sapstartsrv on RHEL 9: + - libxcrypt-compat __sap_general_preconfigure_packages: "{{ lookup('vars', '__sap_general_preconfigure_packages_' + ansible_architecture) }}" diff --git a/roles/sap_ha_pacemaker_cluster/README.md b/roles/sap_ha_pacemaker_cluster/README.md index fa336e05c..9a65edec6 100644 --- a/roles/sap_ha_pacemaker_cluster/README.md +++ b/roles/sap_ha_pacemaker_cluster/README.md @@ -73,7 +73,7 @@ The Ansible Control System (where Ansible is executed from) must have: - Ansible Collection [`redhat.sap_install` from Red Hat Ansible Automation Platform Hub](https://console.redhat.com/ansible/automation-hub/repo/published/redhat/sap_install) version `1.3.0` or later - Ansible Collection [`redhat.rhel_system_roles` from Red Hat Ansible Automation Platform Hub](https://console.redhat.com/ansible/automation-hub/repo/published/redhat/rhel_system_roles) version `1.20.0` or later - **Supported (Downstream)** via RHEL4SAP license: - - RHEL System Roles for SAP RPM Package `rhel-system-roles-3.6.0` or later + - RHEL System Roles for SAP RPM Package `rhel-system-roles-sap-3.6.0` or later - RHEL System Roles RPM Package `rhel-system-roles-1.20.0` or later ## Prerequisites @@ -131,70 +131,85 @@ Red Hat for SAP Community of Practice, Janine Fuchs, IBM Lab for SAP Solutions ## Role Input Parameters -Minimum required parameters: +Minimum required parameters for all clusters: -- [ha_cluster_hacluster_password](#ha_cluster_hacluster_password) -- [sap_hana_instance_number](#sap_hana_instance_number) +- [sap_ha_pacemaker_cluster_hacluster_user_password](#sap_ha_pacemaker_cluster_hacluster_user_password) +Additional minimum requirements depend on the type of cluster setup and on the target platform. -### ha_cluster +### sap_ha_pacemaker_cluster_aws_access_key_id -- _Type:_ `dict` +- _Type:_ `string` -Optional _**host_vars**_ parameter - if defined it must be set for each node.
-Dictionary that can contain various node options for the pacemaker cluster configuration.
-Supported options can be reviewed in the `ha_cluster` Linux System Role [https://github.com/linux-system-roles/ha_cluster/blob/master/README.md].
+AWS access key to allow control of instances (for example for fencing operations).
+Mandatory for the cluster nodes setup on AWS EC2 instances.
-Example: +### sap_ha_pacemaker_cluster_aws_region -```yaml -ha_cluster: - corosync_addresses: - - 192.168.1.10 - - 192.168.2.10 - node_name: nodeA -``` +- _Type:_ `string` -### ha_cluster_cluster_name +The AWS region in which the instances to be used for the cluster setup are located.
+Mandatory for cluster nodes setup on AWS EC2 instances.
-- _Type:_ `str` -- _Default:_ `my-cluster` +### sap_ha_pacemaker_cluster_aws_secret_access_key -The name of the pacemaker cluster.
+- _Type:_ `string` -### ha_cluster_hacluster_password required +AWS secret key, paired with the access key for instance control.
+Mandatory for the cluster setup on AWS EC2 instances.
-- _Type:_ `str` +### sap_ha_pacemaker_cluster_aws_vip_update_rt -The password of the `hacluster` user which is created during pacemaker installation.
+- _Type:_ `string` -### sap_ha_pacemaker_cluster_aws_access_key_id +List one more routing table IDs for managing Virtual IP failover through routing table changes.
+Multiple routing tables must be defined as a comma-separated string (no spaces).
+Mandatory for the VIP resource configuration in AWS EC2 environments.
-- _Type:_ `str` +### sap_ha_pacemaker_cluster_cluster_name -AWS access key to allow control of instances (for example for fencing operations).
-Required for cluster nodes setup on Amazon cloud.
+- _Type:_ `string` -### sap_ha_pacemaker_cluster_aws_region +The name of the pacemaker cluster.
+Inherits the `ha_cluster` LSR native parameter `ha_cluster_cluster_name` if not defined.
+If not defined, the `ha_cluster` Linux System Role default will be used.
-- _Type:_ `str` +### sap_ha_pacemaker_cluster_cluster_nodes -The AWS region in which the instances to be used for the cluster setup are located.
-Required for cluster nodes setup on Amazon cloud.
+- _Type:_ `list` -### sap_ha_pacemaker_cluster_aws_secret_access_key +List of cluster nodes and associated attributes to describe the target SAP HA environment.
+This is required for the HANA System Replication configuration.
+Synonym for this parameter is `sap_hana_cluster_nodes`.
+Mandatory to be defined for HANA clusters.
+ +- **hana_site**
+ Site of the cluster and/or SAP HANA System Replication node (for example 'DC01').
Mandatory for HANA clusters (sudo config for system replication). +- **node_ip**
+ IP address of the node used for HANA System Replication.
_Optional. Currently not needed/used in cluster configuration._ +- **node_name**
+ Name of the cluster node, should match the remote systems' hostnames.
_Optional. Currently not needed/used in cluster configuration._ +- **node_role**
+ Role of the defined `node_name` in the SAP HANA cluster setup.
There must be only **one** primary, but there can be multiple secondary nodes.
_Optional. Currently not needed/used in cluster configuration._ -- _Type:_ `str` +Example: -AWS secret key, paired with the access key for instance control.
-Required for cluster nodes setup on Amazon cloud.
+```yaml +sap_ha_pacemaker_cluster_cluster_nodes: +- hana_site: DC01 + node_ip: 192.168.5.1 + node_name: nodeA + node_role: primary +- hana_site: DC02 +``` ### sap_ha_pacemaker_cluster_cluster_properties - _Type:_ `dict` -- _Default:_ `See example` +- _Default:_ `{'concurrent-fencing': True, 'stonith-enabled': True, 'stonith-timeout': 900}` Standard pacemaker cluster properties are configured with recommended settings for cluster node fencing.
+When no STONITH resource is defined, STONITH will be disabled and a warning displayed.
Example: @@ -207,8 +222,8 @@ sap_ha_pacemaker_cluster_cluster_properties: ### sap_ha_pacemaker_cluster_create_config_dest -- _Type:_ `str` -- _Default:_ `_resource_config.yml` +- _Type:_ `string` +- _Default:_ `review_resource_config.yml` The pacemaker cluster resource configuration optionally created by this role will be saved in a Yaml file in the current working directory.
Requires `sap_ha_pacemaker_cluster_create_config_varfile` to be enabled for generating the output file.
@@ -225,9 +240,39 @@ This allows using the output file later as input file for additional custom step When enabled this parameters file is also created when the playbook is run in check_mode (`--check`) and can be used to review the configuration parameters without executing actual changes on the target nodes.
WARNING! This report may include sensitive details like secrets required for certain cluster resources!
+### sap_ha_pacemaker_cluster_enable_cluster_connector + +- _Type:_ `bool` +- _Default:_ `True` + +Enables/Disables the SAP HA Interface for SAP ABAP application server instances, also known as `sap_cluster_connector`.
+Set this parameter to 'false' if the SAP HA interface should not be installed and configured.
+ +### sap_ha_pacemaker_cluster_extra_packages + +- _Type:_ `list` + +Additional extra packages to be installed, for instance specific resource packages.
+For SAP clusters configured by this role, the relevant standard packages for the target scenario are automatically included.
+ +### sap_ha_pacemaker_cluster_fence_agent_minimal_packages + +- _Type:_ `list` +- _Default:_ `['fence-agents-all']` + +The minimal set of fence agent packages that will be installed.
+ +### sap_ha_pacemaker_cluster_fence_agent_packages + +- _Type:_ `list` + +Additional fence agent packages to be installed.
+This is automatically combined with `sap_ha_pacemaker_cluster_fence_agent_minimal_packages`.
+ ### sap_ha_pacemaker_cluster_fence_options - _Type:_ `dict` +- _Default:_ `{'pcmk_reboot_retries': 4, 'pcmk_reboot_timeout': 400, 'power_timeout': 240}` STONITH resource common parameters that apply to most fencing agents.
These options are applied to fencing resources this role uses automatically for pre-defined platforms (like AWS EC2 VS, IBM Cloud VS).
@@ -243,6 +288,47 @@ sap_ha_pacemaker_cluster_fence_options: power_timeout: 240 ``` +### sap_ha_pacemaker_cluster_gcp_project + +- _Type:_ `string` + +Google Cloud project name in which the target instances are installed.
+Mandatory for the cluster setup on GCP instances.
+ +### sap_ha_pacemaker_cluster_gcp_region_zone + +- _Type:_ `string` + +Google Cloud Platform region zone ID.
+Mandatory for the cluster setup on GCP instances.
+ +### sap_ha_pacemaker_cluster_ha_cluster + +- _Type:_ `dict` + +The `ha_cluster` LSR native parameter `ha_cluster` can be used as a synonym.
+Optional _**host_vars**_ parameter - if defined it must be set for each node.
+Dictionary that can contain various node options for the pacemaker cluster configuration.
+Supported options can be reviewed in the `ha_cluster` Linux System Role [https://github.com/linux-system-roles/ha_cluster/blob/master/README.md].
+If not defined, the `ha_cluster` Linux System Role default will be used.
+ +Example: + +```yaml +sap_ha_pacemaker_cluster_ha_cluster: + corosync_addresses: + - 192.168.1.10 + - 192.168.2.10 + node_name: nodeA +``` + +### sap_ha_pacemaker_cluster_hacluster_user_password required + +- _Type:_ `string` + +The password of the `hacluster` user which is created during pacemaker installation.
+Inherits the value of `ha_cluster_hacluster_password`, when defined.
+ ### sap_ha_pacemaker_cluster_hana_automated_register - _Type:_ `bool` @@ -261,6 +347,14 @@ Time difference needed between to primary time stamps, if a dual-primary situati If the time difference is less than the time gap, then the cluster holds one or both instances in a "WAITING" status.
This is to give an admin a chance to react on a failover. A failed former primary will be registered after the time difference is passed.
+### sap_ha_pacemaker_cluster_hana_instance_nr + +- _Type:_ `string` + +The instance number of the SAP HANA database which this role will configure in the cluster.
+Inherits the value of `sap_hana_instance_number`, when defined.
+Mandatory for SAP HANA cluster setups.
+ ### sap_ha_pacemaker_cluster_hana_prefer_site_takeover - _Type:_ `bool` @@ -270,46 +364,284 @@ Parameter for the 'SAPHana' cluster resource.
Set to "false" if the cluster should first attempt to restart the instance on the same node.
When set to "true" (default) a failover to secondary will be initiated on resource failure.
+### sap_ha_pacemaker_cluster_hana_resource_clone_name + +- _Type:_ `string` +- _Default:_ `SAPHana__-clone` + +Customize the cluster resource name of the SAP HANA DB resource clone.
+ ### sap_ha_pacemaker_cluster_hana_resource_name -- _Type:_ `str` +- _Type:_ `string` - _Default:_ `SAPHana__` Customize the cluster resource name of the SAP HANA DB resource.
+### sap_ha_pacemaker_cluster_hana_sid + +- _Type:_ `string` + +The SAP HANA SID of the instance that will be configured in the cluster.
+The SID must follow SAP specifications - see SAP Note 1979280.
+Inherits the value of `sap_hana_sid`, when defined.
+Mandatory for SAP HANA cluster setups.
+ +### sap_ha_pacemaker_cluster_hana_topology_resource_clone_name + +- _Type:_ `string` +- _Default:_ `SAPHanaTopology__-clone` + +Customize the cluster resource name of the SAP HANA Topology resource clone.
+ ### sap_ha_pacemaker_cluster_hana_topology_resource_name -- _Type:_ `str` +- _Type:_ `string` - _Default:_ `SAPHanaTopology__` Customize the cluster resource name of the SAP HANA Topology resource.
+### sap_ha_pacemaker_cluster_host_type + +- _Type:_ `list` +- _Default:_ `hana_scaleup_perf` + +The SAP landscape to for which the cluster is to be configured.
+The default is a 2-node SAP HANA scale-up cluster.
+ ### sap_ha_pacemaker_cluster_ibmcloud_api_key -- _Type:_ `str` +- _Type:_ `string` + +The API key which is required to allow the control of instances (for example for fencing operations).
+Mandatory for the cluster setup on IBM Cloud Virtual Server instances or IBM Power Virtual Server on IBM Cloud.
+ +### sap_ha_pacemaker_cluster_ibmcloud_powervs_api_type + +- _Type:_ `string` + +IBM Power Virtual Server API Endpoint type (public or private) dependent on network interface attachments for the target instances.
+['Mandatory for the cluster setup on IBM Power Virtual Server from IBM Cloud.']
-The API key is required to allow control of instances (for example for fencing operations).
-Required for cluster nodes setup in IBM Cloud.
+### sap_ha_pacemaker_cluster_ibmcloud_powervs_forward_proxy_url + +- _Type:_ `string` + +IBM Power Virtual Server forward proxy url when IBM Power Virtual Server API Endpoint type is set to private.
+When public network interface, can be ignored.
+When private network interface, mandatory for the cluster setup on IBM Power Virtual Server from IBM Cloud.
+ +### sap_ha_pacemaker_cluster_ibmcloud_powervs_workspace_crn + +- _Type:_ `string` + +IBM Power Virtual Server Workspace service cloud resource name (CRN) identifier which contains the target instances
+Mandatory for the cluster setup on IBM Power Virtual Server from IBM Cloud.
### sap_ha_pacemaker_cluster_ibmcloud_region -- _Type:_ `str` +- _Type:_ `string` + +The IBM Cloud VS region name in which the instances are running.
+Mandatory for the cluster setup on IBM Cloud Virtual Server instances or IBM Power Virtual Server on IBM Cloud.
+ +### sap_ha_pacemaker_cluster_msazure_resource_group + +- _Type:_ `string` + +Resource group name/ID in which the target instances are defined.
+Mandatory for the cluster setup on MS Azure instances.
+ +### sap_ha_pacemaker_cluster_msazure_subscription_id + +- _Type:_ `string` + +Subscription ID of the MS Azure environment containing the target instances.
+Mandatory for the cluster setup on MS Azure instances.
+ +### sap_ha_pacemaker_cluster_nwas_abap_aas_instance_nr + +- _Type:_ `string` + +Instance number of the NetWeaver ABAP AAS instance.
+Mandatory for NetWeaver AAS cluster configuration.
+ +### sap_ha_pacemaker_cluster_nwas_abap_ascs_ers_ensa1 + +- _Type:_ `bool` +- _Default:_ `False` + +The standard NetWeaver ASCS/ERS cluster will be set up as ENSA2.
+Set this parameter to 'true' to configure it as ENSA1.
+ +### sap_ha_pacemaker_cluster_nwas_abap_ascs_filesystem_resource_name + +- _Type:_ `string` +- _Default:_ `Filesystem_NWAS_ABAP_ASCS__` + +Name of the filesystem resource for the ASCS instance.
+ +### sap_ha_pacemaker_cluster_nwas_abap_ascs_group_stickiness -The cloud region key in which the instances are running.
-Required for cluster nodes setup in IBM Cloud.
+- _Type:_ `string` +- _Default:_ `3000` -### sap_ha_pacemaker_cluster_replication_type +NetWeaver ASCS resource group stickiness to prefer the ASCS group to stay on the node it was started on.
-- _Type:_ `str` -- _Default:_ `none` +### sap_ha_pacemaker_cluster_nwas_abap_ascs_instance_nr -The type of SAP HANA site replication across multiple hosts.
-_Not yet supported_
+- _Type:_ `string` + +Instance number of the NetWeaver ABAP ASCS instance.
+Mandatory for NetWeaver ASCS/ERS cluster configuration.
+ +### sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_automatic_recover_bool + +- _Type:_ `bool` +- _Default:_ `False` + +NetWeaver ASCS instance resource option "AUTOMATIC_RECOVER".
+ +### sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_ensa1_failure_timeout + +- _Type:_ `string` +- _Default:_ `60` + +NetWeaver ASCS instance failure-timeout attribute.
+Only used for ENSA1 setups (see `sap_ha_pacemaker_cluster_nwas_abap_ascs_ers_ensa1`). Default setup is ENSA2.
+ +### sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_ensa1_migration_threshold + +- _Type:_ `string` +- _Default:_ `1` + +NetWeaver ASCS instance migration-threshold setting attribute.
+Only used for ENSA1 setups (see `sap_ha_pacemaker_cluster_nwas_abap_ascs_ers_ensa1`). Default setup is ENSA2.
+ +### sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_instance_name + +- _Type:_ `string` + +The name of the ASCS instance, typically the profile name.
+Mandatory for the NetWeaver ASCS/ERS cluster setup
+ +### sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_resource_name + +- _Type:_ `string` +- _Default:_ `SAPInstance_NWAS_ABAP_ASCS__` + +Name of the ASCS instance resource.
+ +### sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_resource_stickiness + +- _Type:_ `string` +- _Default:_ `5000` + +NetWeaver ASCS instance resource stickiness attribute.
+ +### sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_start_profile_string + +- _Type:_ `string` + +The full path and name of the ASCS instance profile.
+Mandatory for the NetWeaver ASCS/ERS cluster setup.
+ +### sap_ha_pacemaker_cluster_nwas_abap_ers_filesystem_resource_name + +- _Type:_ `string` +- _Default:_ `Filesystem_NWAS_ABAP_ERS__` + +Name of the filesystem resource for the ERS instance.
+ +### sap_ha_pacemaker_cluster_nwas_abap_ers_instance_nr + +- _Type:_ `string` + +Instance number of the NetWeaver ABAP ERS instance.
+Mandatory for NetWeaver ASCS/ERS cluster configuration.
+ +### sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_automatic_recover_bool + +- _Type:_ `bool` +- _Default:_ `False` + +NetWeaver ERS instance resource option "AUTOMATIC_RECOVER".
+ +### sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_instance_name + +- _Type:_ `string` + +The name of the ERS instance, typically the profile name.
+Mandatory for the NetWeaver ASCS/ERS cluster setup.
+ +### sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_resource_name + +- _Type:_ `string` +- _Default:_ `SAPInstance_NWAS_ABAP_ERS__` + +Name of the ERS instance resource.
+ +### sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_start_profile_string + +- _Type:_ `string` + +The full path and name of the ERS instance profile.
+Mandatory for the NetWeaver ASCS/ERS cluster.
+ +### sap_ha_pacemaker_cluster_nwas_abap_pas_instance_nr + +- _Type:_ `string` + +Instance number of the NetWeaver ABAP PAS instance.
+Mandatory for NetWeaver PAS cluster configuration.
+ +### sap_ha_pacemaker_cluster_nwas_abap_sid + +- _Type:_ `string` + +SID of the NetWeaver instances.
+Mandatory for NetWeaver cluster configuration.
+Uses `sap_swpm_sid` if defined.
+Mandatory for NetWeaver cluster setups.
+ +### sap_ha_pacemaker_cluster_nwas_sapmnt_filesystem_resource_name + +- _Type:_ `string` +- _Default:_ `Filesystem_NWAS_SAPMNT_` + +Filesystem resource name for the shared filesystem /sapmnt.
+Optional, this is typically managed by the OS, but can as well be added to the cluster configuration.
+Enable this resource setup using `sap_ha_pacemaker_cluster_nwas_shared_filesystems_cluster_managed`.
+ +### sap_ha_pacemaker_cluster_nwas_shared_filesystems_cluster_managed + +- _Type:_ `bool` +- _Default:_ `False` + +Change this parameter to 'true' if the 3 shared filesystems `/usr/sap/trans`, `/usr/sap//SYS` and '/sapmnt' shall be configured as cloned cluster resources.
+ +### sap_ha_pacemaker_cluster_nwas_sys_filesystem_resource_name + +- _Type:_ `string` +- _Default:_ `Filesystem_NWAS_SYS_` + +Filesystem resource name for the transports filesystem /usr/sap//SYS.
+Optional, this is typically managed by the OS, but can as well be added to the cluster configuration.
+Enable this resource setup using `sap_ha_pacemaker_cluster_nwas_shared_filesystems_cluster_managed`.
+ +### sap_ha_pacemaker_cluster_nwas_transports_filesystem_resource_name + +- _Type:_ `string` +- _Default:_ `Filesystem_NWAS_TRANS_` + +Filesystem resource name for the transports filesystem /usr/sap/trans.
+Optional, this is typically managed by the OS, but can as well be added to the cluster configuration.
+Enable this resource setup using `sap_ha_pacemaker_cluster_nwas_shared_filesystems_cluster_managed`.
### sap_ha_pacemaker_cluster_resource_defaults - _Type:_ `dict` -- _Default:_ `See example` +- _Default:_ `{'migration-threshold': 5000, 'resource-stickiness': 3000}` Set default parameters that will be valid for all pacemaker resources.
@@ -321,83 +653,184 @@ sap_ha_pacemaker_cluster_resource_defaults: resource-stickiness: 1000 ``` +### sap_ha_pacemaker_cluster_stonith_custom + +- _Type:_ `list` + +Custom list of STONITH resource(s) to be configured in the cluster.
+This definition override any defaults the role would apply otherwise.
+ +- **agent**
+ Resource agent name, must contain the prefix "stonith:" to avoid mismatches or failures. +- **name**
+ Name that will be used as the resource ID (name). +- **options**
+ The resource options listed in dictionary format, one option per line.
Requires the mandatory options for the particular stonith resource agent to be defined, otherwise the setup will fail. + +Example: + +```yaml +sap_ha_pacemaker_cluster_stonith_custom: +- agent: stonith:fence_rhevm + name: my-fence-resource + options: + ip: rhevm-server + password: login-user-password + pcmk_host_list: node1,node2 + power_wait: 3 + username: login-user +``` + +### sap_ha_pacemaker_cluster_storage_definition + +- _Type:_ `list` + +List of filesystem definitions used for filesystem cluster resources.
+Options relevant, see example.
+Mandatory for SAP NetWeaver HA cluster configurations.
+Reuse `sap_storage_setup_definition` if defined.
+Reuse `sap_storage_setup_definition` will extract values 'mountpoint', 'nfs_filesystem_type', 'nfs_mount_options', 'nfs_path', 'nfs_server'.
+Reuse `sap_storage_setup_definition` all options are documented under Ansible Role `sap_storage_setup`.
+Note! For this variable, the argument specification does not list options, to avoid errors during reuse of `sap_storage_setup_definition` if defined.
+ +Example: + +```yaml +sap_ha_pacemaker_cluster_storage_definition: +- mountpoint: /usr/sap + name: usr_sap + nfs_path: /usr/sap + nfs_server: nfs-server.example.com:/ +- mountpoint: /usr/sap/trans + name: usr_sap_trans + nfs_path: /usr/sap/trans + nfs_server: nfs-server.example.com:/ +- mountpoint: /sapmnt + name: sapmnt + nfs_filesystem_type: nfs + nfs_mount_options: defaults + nfs_path: /sapmnt + nfs_server: nfs-server.example.com:/ +``` + +### sap_ha_pacemaker_cluster_storage_nfs_filesytem_type + +- _Type:_ `string` +- _Default:_ `nfs` + +Filesystem type of the NFS filesystems that are part of the cluster configuration.
+ +### sap_ha_pacemaker_cluster_storage_nfs_mount_options + +- _Type:_ `string` +- _Default:_ `defaults` + +Mount options of the NFS filesystems that are part of the cluster configuration.
+ +### sap_ha_pacemaker_cluster_storage_nfs_server + +- _Type:_ `string` + +Default address of the NFS server, if not defined individually by filesystem.
+ +### sap_ha_pacemaker_cluster_system_roles_collection + +- _Type:_ `string` +- _Default:_ `fedora.linux_system_roles` + +Reference to the Ansible Collection used for the Linux System Roles.
+For community/upstream, use 'fedora.linux_system_roles'.
+For RHEL System Roles for SAP, or Red Hat Automation Hub, use 'redhat.rhel_system_roles'.
+ ### sap_ha_pacemaker_cluster_vip_client_interface -- _Type:_ `str` -- _Default:_ `eth0` +- _Type:_ `string` OS device name of the network interface to use for the Virtual IP configuration.
-This is used for VIP agents that require an interface name, for example in cloud platform environments.
+When there is only one interface on the system, its name will be used by default.
-### sap_ha_pacemaker_cluster_vip_resource_name +### sap_ha_pacemaker_cluster_vip_hana_primary_ip_address -- _Type:_ `str` -- _Default:_ `vip__` +- _Type:_ `string` -Customize the name of the resource managing the Virtual IP.
+The virtual IP of the primary HANA instance.
+Mandatory parameter for HANA clusters.
-### sap_ha_pacemaker_cluster_vip_update_rt +### sap_ha_pacemaker_cluster_vip_hana_primary_resource_name -- _Type:_ `list` +- _Type:_ `string` +- _Default:_ `vip_` -List one more routing table IDs for managing Virtual IP failover through routing table changes.
-Required for VIP configuration in AWS EC2 environments.
+Customize the name of the resource managing the Virtual IP of the primary HANA instance.
-### sap_hana_cluster_nodes +### sap_ha_pacemaker_cluster_vip_hana_secondary_ip_address -- _Type:_ `list` +- _Type:_ `string` -List of cluster nodes and associated attributes to describe the target SAP HA environment.
-This is required for the HANA System Replication configuration.
+The virtual IP for read-only access to the secondary HANA instance.
+Optional parameter in HANA clusters.
-- **hana_site**
- Site of the cluster and/or SAP HANA System Replication node (for example 'DC01').
This is required for HANA System Replication configuration. -- **node_ip**
- IP address of the node used for HANA System Replication. -- **node_name**
- Name of the cluster node, should match the remote systems' hostnames.
This is needed by the cluster members to know all their partner nodes. -- **node_role**
- Role of this node in the SAP cluster setup.
There must be only **one** primary, but there can be multiple secondary nodes. +### sap_ha_pacemaker_cluster_vip_nwas_abap_aas_ip_address -Example: +- _Type:_ `string` -```yaml -sap_hana_cluster_nodes: -- hana_site: DC01 - node_ip: 192.168.5.1 - node_name: nodeA - node_role: primary -- hana_site: DC02 - node_ip: 192.168.5.2 - node_name: nodeB - node_role: secondary -``` +Virtual IP of the NetWeaver AAS instance.
+Mandatory for NetWeaver AAS cluster setup.
-### sap_hana_instance_number required +### sap_ha_pacemaker_cluster_vip_nwas_abap_aas_resource_name -- _Type:_ `str` +- _Type:_ `string` +- _Default:_ `vip___aas` -The instance number of the SAP HANA database which is role will configure in the cluster.
+Name of the SAPInstance resource for NetWeaver AAS.
-### sap_hana_sid +### sap_ha_pacemaker_cluster_vip_nwas_abap_ascs_ip_address -- _Type:_ `str` +- _Type:_ `string` -The SAP HANA SID of the instance that will be configured in the cluster.
-The SID must follow SAP specifications - see SAP Note 1979280.
+Virtual IP of the NetWeaver ASCS instance.
+Mandatory for NetWeaver ASCS/ERS cluster setup.
-### sap_hana_vip +### sap_ha_pacemaker_cluster_vip_nwas_abap_ascs_resource_name -- _Type:_ `dict` +- _Type:_ `string` +- _Default:_ `vip___ascs` -One floating IP is required for SAP HANA DB connection by clients.
-This main VIP will always run on the promoted HANA node and be moved with it during a failover.
+Name of the SAPInstance resource for NetWeaver ASCS.
-Example: +### sap_ha_pacemaker_cluster_vip_nwas_abap_ers_ip_address -```yaml -sap_hana_vip: - primary: 192.168.10.100 -``` +- _Type:_ `string` + +Virtual IP of the NetWeaver ERS instance.
+Mandatory for NetWeaver ASCS/ERS cluster setup.
+ +### sap_ha_pacemaker_cluster_vip_nwas_abap_ers_resource_name + +- _Type:_ `string` +- _Default:_ `vip___ers` + +Name of the SAPInstance resource for NetWeaver ERS.
+ +### sap_ha_pacemaker_cluster_vip_nwas_abap_pas_ip_address + +- _Type:_ `string` + +Virtual IP of the NetWeaver PAS instance.
+Mandatory for NetWeaver PAS cluster setup.
+ +### sap_ha_pacemaker_cluster_vip_nwas_abap_pas_resource_name + +- _Type:_ `string` +- _Default:_ `vip___pas` + +Name of the SAPInstance resource for NetWeaver PAS.
+ +### sap_ha_pacemaker_cluster_vip_secondary_resource_name + +- _Type:_ `string` +- _Default:_ `vip_` + +Customize the name of the resource managing the Virtual IP of read-only access to the secondary HANA instance.
diff --git a/roles/sap_ha_pacemaker_cluster/defaults/main.yml b/roles/sap_ha_pacemaker_cluster/defaults/main.yml index ac0cb4696..b4652cb72 100644 --- a/roles/sap_ha_pacemaker_cluster/defaults/main.yml +++ b/roles/sap_ha_pacemaker_cluster/defaults/main.yml @@ -1,4 +1,11 @@ --- +################################################################################ +# Role generic parameters +################################################################################ + +# Do NOT USE ANSIBLE FACTS for defaults to be compatible with +# playbooks that disable generic fact gathering! + # Set which Ansible Collection to use for the Linux System Roles. # For community/upstream, use 'fedora.linux_system_roles' # For the RHEL System Roles for SAP, or for Red Hat Automation Hub, use 'redhat.rhel_system_roles' @@ -6,77 +13,51 @@ sap_ha_pacemaker_cluster_system_roles_collection: 'fedora.linux_system_roles' # Variables for the cluster setup must be constructed by dedicated tasks! # The included 'ha_cluster' role will not work with the role variables set -# in this role. +# in this role. This SAP HA role takes care of the parameter construction +# based on the target cluster to be configured, before feeding it into 'ha_cluster'. -# Do NOT USE ANSIBLE FACTS for defaults to be compatible with -# playbooks that disable generic fact gathering! - -sap_ha_pacemaker_cluster_cluster_name: "{{ ha_cluster_cluster_name | default('my-cluster') }}" +# Optional: write all cluster configuration (including unencrypted credentials!) into a yaml +# config file. +# Useful for parameter review or re-use with the 'ha_cluster' LSR. sap_ha_pacemaker_cluster_create_config_varfile: false -sap_ha_pacemaker_cluster_create_config_dest: "{{ sap_ha_pacemaker_cluster_cluster_name }}_resource_config.yml" +sap_ha_pacemaker_cluster_create_config_dest: "review_resource_config.yml" -# Inherit SAP common (global synonyms) parameters -sap_ha_pacemaker_cluster_cluster_nodes: "{{ sap_ha_cluster_nodes | default(sap_hana_cluster_nodes) }}" -sap_ha_pacemaker_cluster_hana_sid: "{{ sap_hana_sid | default('') }}" -sap_ha_pacemaker_cluster_hana_instance_number: "{{ sap_hana_instance_number | default('00') }}" +# Inherit SAP common (global synonyms) parameters when defined. -sap_ha_pacemaker_cluster_storage_definition: "{{ sap_storage_definition | default([]) }}" -sap_ha_pacemaker_cluster_storage_nfs_filesytem_type: nfs4 -sap_ha_pacemaker_cluster_storage_nfs_mount_options: hard,acl -sap_ha_pacemaker_cluster_storage_nfs_server: "{{ sap_storage_nfs_server | default('') }}" +# This variable is currently only required for HANA nodes to define +# - hana_site: +# Other options are needed in the separate HSR setup role. +sap_ha_pacemaker_cluster_cluster_nodes: "{{ sap_hana_cluster_nodes | default([]) }}" -sap_ha_pacemaker_cluster_netweaver_sid: "{{ sap_swpm_sid | default('') }}" -sap_ha_pacemaker_cluster_netweaver_abap_ascs_instance_number: "{{ sap_swpm_ascs_instance_nr }}" -sap_ha_pacemaker_cluster_netweaver_abap_ers_instance_number: "{{ sap_swpm_ers_instance_nr }}" -sap_ha_pacemaker_cluster_netweaver_abap_pas_instance_number: "{{ sap_swpm_pas_instance_nr }}" -sap_ha_pacemaker_cluster_netweaver_abap_aas_instance_number: "{{ sap_swpm_aas_instance_nr }}" -sap_ha_pacemaker_cluster_netweaver_java_scs_instance_number: "{{ sap_swpm_java_scs_instance_nr }}" -sap_ha_pacemaker_cluster_netweaver_java_ers_instance_number: "{{ sap_swpm_java_ers_instance_nr }}" - -#sap_ha_pacemaker_cluster_netweaver_common_filesystems: -# - /sapmnt -# - /usr/sap/trans -# - "/usr/sap/{{ sap_ha_pacemaker_cluster_netweaver_sid }}/SYS" - -# The following directories are appended to the 'nfs_path' of the '/usr/sap' storage -# definition. -# Therefore, the /usr/sap prefix must be left out of the listed path items. -sap_ha_pacemaker_cluster_netweaver_abap_ascs_ers_filesystems: - - "{{ sap_ha_pacemaker_cluster_netweaver_sid }}/ASCS{{ sap_ha_pacemaker_cluster_netweaver_abap_ascs_instance_number }}" - - "{{ sap_ha_pacemaker_cluster_netweaver_sid }}/ERS{{ sap_ha_pacemaker_cluster_netweaver_abap_ers_instance_number }}" - -# Make sure that there is always the default fed into the included role -sap_ha_pacemaker_cluster_fence_agent_packages: +# Make sure that there is always the minimal default fed into the included role. +# This is combined with the custom list 'sap_ha_pacemaker_cluster_fence_agent_packages'. +sap_ha_pacemaker_cluster_fence_agent_minimal_packages: - fence-agents-all -sap_ha_pacemaker_cluster_extra_packages: "{{ ha_cluster_extra_packages | default([]) }}" - -# Adjusting resource defaults -sap_ha_pacemaker_cluster_resource_defaults: - resource-stickiness: 1000 - migration-threshold: 5000 +# Resource defaults are defined differently by cluster type in different tasks, if not custom defined. +# TODO: migrate to 'ha_cluster' native parameter combination when moving the function to be included in the role +# (newer feature in the LSR) +sap_ha_pacemaker_cluster_resource_defaults: {} # The type of SAP landscape and multi-node replication # TODO: Type definitions and feature support # TODO: Implement all types # hana_scaleup_costopt (not yet) -# hana_scaleup_perf (default) +# hana_scaleup_perf (available, default) # hana_scaleup_per_dr (not yet) # hana_scaleout (not yet) -# nwas_abap_ascs_ers -# nwas_abap_pas_aas +# nwas_abap_ascs_ers (available) +# nwas_abap_pas_aas (not yet) # nwas_java_scs_ers (maybe) -sap_ha_pacemaker_cluster_host_type: "{{ sap_host_type | default('hana_scaleup_perf') }}" -sap_ha_pacemaker_cluster_replication_type: none -# Optional parameters to customize HANA resources -# AUTOMATED_REGISTER -sap_ha_pacemaker_cluster_hana_automated_register: true -# DUPLICATE_PRIMARY_TIMEOUT -sap_ha_pacemaker_cluster_hana_duplicate_primary_timeout: 900 -# PREFER_SITE_TAKEOVER -sap_ha_pacemaker_cluster_hana_prefer_site_takeover: true +# 'sap_ha_pacemaker_cluster_host_type' is converted from string to list type in +# 'tasks/ascertain_sap_landscape.yml'. +# TODO: review with testers, updated arg specs now require it to be a list from the start +sap_ha_pacemaker_cluster_host_type: "{{ sap_host_type | default(['hana_scaleup_perf']) }}" + +# Currently unused parameter. Keeping for future functionality. +#sap_ha_pacemaker_cluster_replication_type: none ### stonith resource parameter defaults sap_ha_pacemaker_cluster_fence_options: @@ -84,99 +65,242 @@ sap_ha_pacemaker_cluster_fence_options: pcmk_reboot_timeout: 400 power_timeout: 240 -### Resource default patterns -sap_ha_pacemaker_cluster_vip_address: "{{ sap_hana_vip | default(sap_cluster_vip) }}" +### VIP resource default patterns +# Currently there is no task for a different default VIP resource agent. +# Leaving out of meta/argument_specs.yml. +# Platform specific defaults are defined separately. sap_ha_pacemaker_cluster_vip_resource_agent: "ocf:heartbeat:IPaddr2" -sap_ha_pacemaker_cluster_vip_resource_name: "vip_{{ sap_ha_pacemaker_cluster_hana_sid }}_{{ sap_ha_pacemaker_cluster_hana_instance_number }}" +sap_ha_pacemaker_cluster_vip_client_interface: '' + +## A custom stonith definition that takes precedence over platform defaults. +# sap_ha_pacemaker_cluster_stonith_custom: +# - name: "" +# agent: "stonith:" +# options: +# pcmk_host_list: "" + +#sap_ha_pacemaker_cluster_stonith_custom: [] + +# Simpler definition format here which gets transformed into the 'ha_cluster' LSR native +# 'ha_cluster_cluster_properties' parameter. +sap_ha_pacemaker_cluster_cluster_properties: + stonith-enabled: true + stonith-timeout: 900 + concurrent-fencing: true + +################################################################################ +# Inherit from 'ha_cluster' Linux System Role parameters when defined +################################################################################ + +# Optional without a default. The 'ha_cluster' LSR defaults will apply when not defined. +#sap_ha_pacemaker_cluster_ha_cluster: +#sap_ha_pacemaker_cluster_cluster_name: + +# Optional. Set a default here and not in the code. +sap_ha_pacemaker_cluster_extra_packages: [] + +# Optional: additional fence agent packages. This is combined with the above "minimal" list. +sap_ha_pacemaker_cluster_fence_agent_packages: [] + +# Mandatory. +# Either inherit from the 'ha_cluster' LSR variable when defined, but do not set a default. +# This fails the argument validation when none of the 2 vars are defined. +sap_ha_pacemaker_cluster_hacluster_user_password: "{{ ha_cluster_hacluster_password }}" + + +################################################################################ +# HANA +################################################################################ + +sap_ha_pacemaker_cluster_hana_sid: "{{ sap_hana_sid | default('') }}" +# Keeping 'sap_ha_pacemaker_cluster_hana_instance_number' for the time being for backwards compatibility. +sap_ha_pacemaker_cluster_hana_instance_nr: "{{ sap_ha_pacemaker_cluster_hana_instance_number | default(sap_hana_instance_number) | default('') }}" + +# Optional parameters to customize SAPHana resources +# AUTOMATED_REGISTER +sap_ha_pacemaker_cluster_hana_automated_register: true +# DUPLICATE_PRIMARY_TIMEOUT +sap_ha_pacemaker_cluster_hana_duplicate_primary_timeout: 900 +# PREFER_SITE_TAKEOVER +sap_ha_pacemaker_cluster_hana_prefer_site_takeover: true + # SAP HANA - Resource IDs (names) as convenience parameters. -sap_ha_pacemaker_cluster_hana_resource_name: "SAPHana_{{ sap_ha_pacemaker_cluster_hana_sid }}_{{ sap_ha_pacemaker_cluster_hana_instance_number }}" +sap_ha_pacemaker_cluster_hana_resource_name: "SAPHana_{{ sap_ha_pacemaker_cluster_hana_sid }}_{{ sap_ha_pacemaker_cluster_hana_instance_nr }}" sap_ha_pacemaker_cluster_hana_resource_clone_name: "{{ sap_ha_pacemaker_cluster_hana_resource_name }}-clone" -sap_ha_pacemaker_cluster_hana_topology_resource_name: "SAPHanaTopology_{{ sap_ha_pacemaker_cluster_hana_sid }}_{{ sap_ha_pacemaker_cluster_hana_instance_number }}" +sap_ha_pacemaker_cluster_hana_topology_resource_name: "SAPHanaTopology_{{ sap_ha_pacemaker_cluster_hana_sid }}_{{ sap_ha_pacemaker_cluster_hana_instance_nr }}" sap_ha_pacemaker_cluster_hana_topology_resource_clone_name: "{{ sap_ha_pacemaker_cluster_hana_topology_resource_name }}-clone" +# Multiple VIP parameters can be defined and will be combined. +# See tasks/include_construct_vip_resources.yml +# +# Mandatory: primary VIP address definition in HANA scale-up clusters +sap_ha_pacemaker_cluster_vip_hana_primary_ip_address: '' +sap_ha_pacemaker_cluster_vip_hana_primary_resource_name: "vip_{{ sap_ha_pacemaker_cluster_hana_sid }}_{{ sap_ha_pacemaker_cluster_hana_instance_nr }}_primary" +sap_ha_pacemaker_cluster_vip_hana_secondary_ip_address: '' +sap_ha_pacemaker_cluster_vip_hana_secondary_resource_name: "vip_{{ sap_ha_pacemaker_cluster_hana_sid }}_{{ sap_ha_pacemaker_cluster_hana_instance_nr }}_readonly" + + +################################################################################ +# NetWeaver generic definitions +################################################################################ + +# Default will be ENSA2. To configure HA resources for ENSA1, +# set this parameter to 'true'. +sap_ha_pacemaker_cluster_nwas_abap_ascs_ers_ensa1: false + +# Enable/Disable sap_cluster_connector. +# Ref.: https://access.redhat.com/solutions/3606101 +sap_ha_pacemaker_cluster_enable_cluster_connector: true + +# Inherit common synonym NetWeaver parameters when defined. +sap_ha_pacemaker_cluster_nwas_abap_sid: "{{ sap_swpm_sid | default('') }}" +sap_ha_pacemaker_cluster_nwas_abap_ascs_instance_nr: "{{ sap_swpm_ascs_instance_nr | default('') }}" +sap_ha_pacemaker_cluster_nwas_abap_ers_instance_nr: "{{ sap_swpm_ers_instance_nr | default('') }}" +sap_ha_pacemaker_cluster_nwas_abap_pas_instance_nr: "{{ sap_swpm_pas_instance_nr | default('') }}" +sap_ha_pacemaker_cluster_nwas_abap_aas_instance_nr: "{{ sap_swpm_aas_instance_nr | default('') }}" +# Prepare in case JAVA SCS/ERS will be included later. +#sap_ha_pacemaker_cluster_nwas_java_scs_instance_nr: "{{ sap_swpm_java_scs_instance_nr | default('') }}" +#sap_ha_pacemaker_cluster_nwas_java_ers_instance_nr: "{{ sap_swpm_java_ers_instance_nr | default('') }}" + +# Definitions for filesystems resources. Currently limited to NFS filesystems. +sap_ha_pacemaker_cluster_storage_definition: "{{ sap_storage_setup_definition | default([]) }}" +sap_ha_pacemaker_cluster_storage_nfs_filesytem_type: nfs +sap_ha_pacemaker_cluster_storage_nfs_mount_options: 'defaults' +sap_ha_pacemaker_cluster_storage_nfs_server: "{{ sap_storage_nfs_server | default('') }}" + +# NFS filesystem resource requirement +# Not adding to argument_specs because this should not be changed anyway. +# TODO: review later and move to internal vars in vars/main.yml? sap_ha_pacemaker_cluster_resource_filesystem_force_unmount: safe -# SAP NetWeaver common - Resource IDs (names) as convenience parameters. +# Multiple VIP parameters can be defined and will be combined. +# See tasks/include_construct_vip_resources.yml +sap_ha_pacemaker_cluster_vip_nwas_abap_ascs_ip_address: '' +sap_ha_pacemaker_cluster_vip_nwas_abap_ascs_resource_name: "vip_{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_instance_nr }}_ascs" +sap_ha_pacemaker_cluster_vip_nwas_abap_ers_ip_address: '' +sap_ha_pacemaker_cluster_vip_nwas_abap_ers_resource_name: "vip_{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_{{ sap_ha_pacemaker_cluster_nwas_abap_ers_instance_nr }}_ers" +sap_ha_pacemaker_cluster_vip_nwas_abap_pas_ip_address: '' +sap_ha_pacemaker_cluster_vip_nwas_abap_pas_resource_name: "vip_{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_{{ sap_ha_pacemaker_cluster_nwas_abap_pas_instance_nr }}_pas" +sap_ha_pacemaker_cluster_vip_nwas_abap_aas_ip_address: '' +sap_ha_pacemaker_cluster_vip_nwas_abap_aas_resource_name: "vip_{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_{{ sap_ha_pacemaker_cluster_nwas_abap_aas_instance_nr }}_aas" + + +# SAP NetWeaver common - Resource IDs (names) as convenience parameters +# for the following filesystems: # - /sapmnt # - /usr/sap/trans # - /usr/sap/<>/SYS -sap_ha_pacemaker_cluster_netweaver_sapmnt_filesystem_resource_name: "Filesystem_NWAS_SAPMNT_{{ sap_ha_pacemaker_cluster_netweaver_sid }}" -sap_ha_pacemaker_cluster_netweaver_transports_filesystem_resource_name: "Filesystem_NWAS_TRANS_{{ sap_ha_pacemaker_cluster_netweaver_sid }}" -sap_ha_pacemaker_cluster_netweaver_sys_filesystem_resource_name: "Filesystem_NWAS_SYS_{{ sap_ha_pacemaker_cluster_netweaver_sid }}" +sap_ha_pacemaker_cluster_nwas_sapmnt_filesystem_resource_name: "Filesystem_NWAS_SAPMNT_{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}" +sap_ha_pacemaker_cluster_nwas_transports_filesystem_resource_name: "Filesystem_NWAS_TRANS_{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}" +sap_ha_pacemaker_cluster_nwas_sys_filesystem_resource_name: "Filesystem_NWAS_SYS_{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}" + +# The shared filesystems are not required to be configured in the cluster. +# By default it is assumed that they are mounted by the system and available on all cluster nodes. +# Set this parameter to "true" to configure the 3 shared filesystems as part of the cluster. +sap_ha_pacemaker_cluster_nwas_shared_filesystems_cluster_managed: false + + +################################################################################ +# ASCS resource defaults +################################################################################ + +# Name of the instance profile - mandatory to be user-defined +sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_instance_name: '' +# Full path with instance profile name - mandatory to be user-defined +sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_start_profile_string: '' # SAP NetWeaver ABAP ASCS/ERS - Resource IDs (names) as convenience parameters. # - /usr/sap/<>/ASCS<> # - /usr/sap/<>/ERS<> -sap_ha_pacemaker_cluster_netweaver_abap_ascs_filesystem_resource_name: "Filesystem_NWAS_ABAP_ASCS_{{ sap_ha_pacemaker_cluster_netweaver_sid }}_{{ sap_ha_pacemaker_cluster_netweaver_abap_ascs_instance_number }}" -sap_ha_pacemaker_cluster_netweaver_abap_ascs_sapinstance_resource_name: "SAPInstance_NWAS_ABAP_ASCS_{{ sap_ha_pacemaker_cluster_netweaver_sid }}_{{ sap_ha_pacemaker_cluster_netweaver_abap_ascs_instance_number }}" -sap_ha_pacemaker_cluster_netweaver_abap_ascs_sapinstance_resource_clone_name: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ascs_sapinstance_resource_name }}-clone" -sap_ha_pacemaker_cluster_netweaver_abap_ers_filesystem_resource_name: "Filesystem_NWAS_ABAP_ERS_{{ sap_ha_pacemaker_cluster_netweaver_sid }}_{{ sap_ha_pacemaker_cluster_netweaver_abap_ers_instance_number }}" -sap_ha_pacemaker_cluster_netweaver_abap_ers_sapinstance_resource_name: "SAPInstance_NWAS_ABAP_ERS_{{ sap_ha_pacemaker_cluster_netweaver_sid }}_{{ sap_ha_pacemaker_cluster_netweaver_abap_ers_instance_number }}" -sap_ha_pacemaker_cluster_netweaver_abap_ers_sapinstance_resource_clone_name: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ers_sapinstance_resource_name }}-clone" +sap_ha_pacemaker_cluster_nwas_abap_ascs_filesystem_resource_name: "Filesystem_NWAS_ABAP_ASCS_{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_instance_nr }}" +sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_resource_name: "SAPInstance_NWAS_ABAP_ASCS_{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_instance_nr }}" +#sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_resource_clone_name: "{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_resource_name }}-clone" +sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_automatic_recover_bool: false +sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_resource_stickiness: 5000 +sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_ensa1_migration_threshold: 1 +sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_ensa1_failure_timeout: 60 + +# Stickiness of the ASCS group +sap_ha_pacemaker_cluster_nwas_abap_ascs_group_stickiness: 3000 + +################################################################################ +# ERS resource defaults +################################################################################ + +# Name of the instance profile - mandatory to be user-defined +sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_instance_name: '' + +# Full path with instance profile name - mandatory to be user-defined +sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_start_profile_string: '' + +sap_ha_pacemaker_cluster_nwas_abap_ers_filesystem_resource_name: "Filesystem_NWAS_ABAP_ERS_{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_{{ sap_ha_pacemaker_cluster_nwas_abap_ers_instance_nr }}" +sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_resource_name: "SAPInstance_NWAS_ABAP_ERS_{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_{{ sap_ha_pacemaker_cluster_nwas_abap_ers_instance_nr }}" +#sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_resource_clone_name: "{{ sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_resource_name }}-clone" +sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_automatic_recover_bool: false + + +################################################################################ +# PAS/AAS resource defaults +################################################################################ # SAP NetWeaver ABAP PAS/AAS - Resource IDs (names) as convenience parameters. # - /usr/sap/<>/D<> -#sap_ha_pacemaker_cluster_netweaver_abap_pas_filesystem_resource_name: "Filesystem_NWAS_ABAP_PAS_{{ sap_ha_pacemaker_cluster_netweaver_sid }}_{{ sap_ha_pacemaker_cluster_netweaver_abap_pas_instance_number }}" -#sap_ha_pacemaker_cluster_netweaver_abap_pas_sapinstance_resource_name: "SAPInstance_NWAS_ABAP_PAS_{{ sap_ha_pacemaker_cluster_netweaver_sid }}_{{ sap_ha_pacemaker_cluster_netweaver_abap_pas_instance_number }}" -#sap_ha_pacemaker_cluster_netweaver_abap_aas_filesystem_resource_name: "Filesystem_NWAS_ABAP_AAS_{{ sap_ha_pacemaker_cluster_netweaver_sid }}_{{ sap_ha_pacemaker_cluster_netweaver_abap_aas_instance_number }}" -#sap_ha_pacemaker_cluster_netweaver_abap_aas_sapinstance_resource_name: "SAPInstance_NWAS_ABAP_AAS_{{ sap_ha_pacemaker_cluster_netweaver_sid }}_{{ sap_ha_pacemaker_cluster_netweaver_abap_aas_instance_number }}" +#sap_ha_pacemaker_cluster_nwas_abap_pas_filesystem_resource_name: "Filesystem_NWAS_ABAP_PAS_{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_{{ sap_ha_pacemaker_cluster_nwas_abap_pas_instance_nr }}" +#sap_ha_pacemaker_cluster_nwas_abap_pas_sapinstance_resource_name: "SAPInstance_NWAS_ABAP_PAS_{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_{{ sap_ha_pacemaker_cluster_nwas_abap_pas_instance_nr }}" +#sap_ha_pacemaker_cluster_nwas_abap_aas_filesystem_resource_name: "Filesystem_NWAS_ABAP_AAS_{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_{{ sap_ha_pacemaker_cluster_nwas_abap_aas_instance_nr }}" +#sap_ha_pacemaker_cluster_nwas_abap_aas_sapinstance_resource_name: "SAPInstance_NWAS_ABAP_AAS_{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_{{ sap_ha_pacemaker_cluster_nwas_abap_aas_instance_nr }}" +################################################################################ +# JAVA SCS/ERS resource defaults +################################################################################ # SAP NetWeaver JAVA SCS/ERS - Resource IDs (names) as convenience parameters. # - /usr/sap/<>/SCS<> # - /usr/sap/<>/ERS<> -#sap_ha_pacemaker_cluster_netweaver_java_scs_filesystem_resource_name: "Filesytem_NWAS_JAVA_SCS_{{ sap_ha_pacemaker_cluster_netweaver_sid }}_{{ sap_ha_pacemaker_cluster_netweaver_java_scs_instance_number }}" -#sap_ha_pacemaker_cluster_netweaver_java_scs_sapinstance_resource_name: "SAPInstance_NWAS_JAVA_SCS_{{ sap_ha_pacemaker_cluster_netweaver_sid }}_{{ sap_ha_pacemaker_cluster_netweaver_java_scs_instance_number }}" -#sap_ha_pacemaker_cluster_netweaver_java_scs_sapinstance_resource_clone_name: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ascs_sapinstance_resource_name }}-clone" -#sap_ha_pacemaker_cluster_netweaver_java_ers_filesystem_resource_name: "Filesytem_NWAS_JAVA_ERS_{{ sap_ha_pacemaker_cluster_netweaver_sid }}_{{ sap_ha_pacemaker_cluster_netweaver_java_ers_instance_number }}" -#sap_ha_pacemaker_cluster_netweaver_java_ers_sapinstance_resource_name: "SAPInstance_NWAS_JAVA_ERS_{{ sap_ha_pacemaker_cluster_netweaver_sid }}_{{ sap_ha_pacemaker_cluster_netweaver_java_ers_instance_number }}" -#sap_ha_pacemaker_cluster_netweaver_java_ers_sapinstance_resource_clone_name: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ers_sapinstance_resource_name }}-clone" +#sap_ha_pacemaker_cluster_nwas_java_scs_filesystem_resource_name: "Filesytem_NWAS_JAVA_SCS_{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_{{ sap_ha_pacemaker_cluster_nwas_java_scs_instance_nr }}" +#sap_ha_pacemaker_cluster_nwas_java_scs_sapinstance_resource_name: "SAPInstance_NWAS_JAVA_SCS_{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_{{ sap_ha_pacemaker_cluster_nwas_java_scs_instance_nr }}" +#sap_ha_pacemaker_cluster_nwas_java_scs_sapinstance_resource_clone_name: "{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_resource_name }}-clone" +#sap_ha_pacemaker_cluster_nwas_java_ers_filesystem_resource_name: "Filesytem_NWAS_JAVA_ERS_{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_{{ sap_ha_pacemaker_cluster_nwas_java_ers_instance_nr }}" +#sap_ha_pacemaker_cluster_nwas_java_ers_sapinstance_resource_name: "SAPInstance_NWAS_JAVA_ERS_{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_{{ sap_ha_pacemaker_cluster_nwas_java_ers_instance_nr }}" +#sap_ha_pacemaker_cluster_nwas_java_ers_sapinstance_resource_clone_name: "{{ sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_resource_name }}-clone" -# TODO: network interface name used for client access -sap_ha_pacemaker_cluster_vip_client_interface: eth0 -sap_ha_pacemaker_cluster_vip_update_rt: [] - -## A custom stonith definition that takes precedence over platform defaults. -# sap_ha_pacemaker_cluster_stonith_custom: -# - name: "" -# agent: "stonith:" -# options: -# pcmk_host_list: "" - -# Simpler format translated into 'ha_cluster_cluster_properties' format of -# 'ha_cluster' LSR. -sap_ha_pacemaker_cluster_cluster_properties: - stonith-enabled: true - stonith-timeout: 900 - concurrent-fencing: true - +################################################################################ +# Platform specific +################################################################################ ## Infrastructure Platform variables, shown here for visibility only and should not be given default values -## + ## AWS platform, EC2 Virtual Servers +# sap_ha_pacemaker_cluster_aws_vip_update_rt # sap_ha_pacemaker_cluster_aws_access_key_id # sap_ha_pacemaker_cluster_aws_secret_access_key # sap_ha_pacemaker_cluster_aws_region -## + ## Google Cloud platform, Compute Engine Virtual Machines # sap_ha_pacemaker_cluster_gcp_project # sap_ha_pacemaker_cluster_gcp_region_zone -## + ## IBM Cloud platform, Virtual Servers (x86_64) # sap_ha_pacemaker_cluster_ibmcloud_api_key # sap_ha_pacemaker_cluster_ibmcloud_region -## + ## IBM Cloud platform, IBM Power Virtual Servers (ppc64le) # sap_ha_pacemaker_cluster_ibmcloud_api_key # sap_ha_pacemaker_cluster_ibmcloud_region # sap_ha_pacemaker_cluster_ibmcloud_powervs_workspace_crn -# sap_ha_pacemaker_cluster_ibmcloud_powervs_workspace_guid # sap_ha_pacemaker_cluster_ibmcloud_powervs_api_type # sap_ha_pacemaker_cluster_ibmcloud_powervs_forward_proxy_url -## + +## IBM PowerVM hypervisor, Virtual Machines (LPAR, ppc64le) +# sap_ha_pacemaker_cluster_ibmpower_vm_hmc_host +# sap_ha_pacemaker_cluster_ibmpower_vm_hmc_host_port # default, SSH Port 22 +# sap_ha_pacemaker_cluster_ibmpower_vm_hmc_host_login +# sap_ha_pacemaker_cluster_ibmpower_vm_hmc_host_login_password +# sap_ha_pacemaker_cluster_ibmpower_vm_hmc_host_version + ## MS Azure platform, Virtual Machines # sap_ha_pacemaker_cluster_msazure_subscription_id # sap_ha_pacemaker_cluster_msazure_resource_group diff --git a/roles/sap_ha_pacemaker_cluster/meta/argument_specs.yml b/roles/sap_ha_pacemaker_cluster/meta/argument_specs.yml index e7495ee9d..1bd4d0050 100644 --- a/roles/sap_ha_pacemaker_cluster/meta/argument_specs.yml +++ b/roles/sap_ha_pacemaker_cluster/meta/argument_specs.yml @@ -27,124 +27,268 @@ argument_specs: # description: # ... - ha_cluster: + ######################################################################### + # SAP HA role generic parameters + ######################################################################### + sap_ha_pacemaker_cluster_system_roles_collection: + default: fedora.linux_system_roles description: - - Optional _**host_vars**_ parameter - if defined it must be set for each node. - - Dictionary that can contain various node options for the pacemaker cluster configuration. - - Supported options can be reviewed in the `ha_cluster` Linux System Role [https://github.com/linux-system-roles/ha_cluster/blob/master/README.md]. + - Reference to the Ansible Collection used for the Linux System Roles. + - For community/upstream, use 'fedora.linux_system_roles'. + - For RHEL System Roles for SAP, or Red Hat Automation Hub, use 'redhat.rhel_system_roles'. + + sap_ha_pacemaker_cluster_create_config_dest: + default: review_resource_config.yml + description: + - The pacemaker cluster resource configuration optionally created by this role will be saved in a Yaml file in the current working directory. + - Requires `sap_ha_pacemaker_cluster_create_config_varfile` to be enabled for generating the output file. + - Specify a path/filename to save the file in a custom location. + - The file can be used as input vars file for an Ansible playbook running the 'ha_cluster' Linux System Role. + + sap_ha_pacemaker_cluster_create_config_varfile: + type: bool + default: false + description: + - When enabled, all cluster configuration parameters this role constructs for executing the 'ha_cluster' Linux System role will be written into a file in Yaml format. + - This allows using the output file later as input file for additional custom steps using the 'ha_cluster' role and covering the resource configuration in a cluster that was set up using this 'sap_ha_pacemaker_cluster' role. + - When enabled this parameters file is also created when the playbook is run in check_mode (`--check`) and can be used to review the configuration parameters without executing actual changes on the target nodes. + - WARNING! This report may include sensitive details like secrets required for certain cluster resources! + + sap_ha_pacemaker_cluster_cluster_nodes: + type: list + description: + - List of cluster nodes and associated attributes to describe the target SAP HA environment. + - This is required for the HANA System Replication configuration. + - Synonym for this parameter is `sap_hana_cluster_nodes`. + - Mandatory to be defined for HANA clusters. + elements: dict + options: + node_ip: + description: + - IP address of the node used for HANA System Replication. + - _Optional. Currently not needed/used in cluster configuration._ + node_name: + description: + - Name of the cluster node, should match the remote systems' hostnames. + - _Optional. Currently not needed/used in cluster configuration._ + node_role: + choices: + - primary + - secondary + description: + - Role of the defined `node_name` in the SAP HANA cluster setup. + - There must be only **one** primary, but there can be multiple secondary nodes. + - _Optional. Currently not needed/used in cluster configuration._ + hana_site: + description: + - Site of the cluster and/or SAP HANA System Replication node (for example 'DC01'). + - Mandatory for HANA clusters (sudo config for system replication). + example: - ha_cluster: - corosync_addresses: - - 192.168.1.10 - - 192.168.2.10 - node_name: nodeA + sap_ha_pacemaker_cluster_cluster_nodes: + - hana_site: DC01 + node_name: nodeA + node_role: primary + node_ip: 192.168.5.1 + - hana_site: DC02 - required: false - type: dict + sap_ha_pacemaker_cluster_fence_agent_minimal_packages: + type: list + default: ['fence-agents-all'] + description: + - The minimal set of fence agent packages that will be installed. - ha_cluster_cluster_name: - default: my-cluster + sap_ha_pacemaker_cluster_resource_defaults: + type: dict + default: + resource-stickiness: 3000 + migration-threshold: 5000 description: - - The name of the pacemaker cluster. - required: false - type: str + - Set default parameters that will be valid for all pacemaker resources. + example: + sap_ha_pacemaker_cluster_resource_defaults: + resource-stickiness: 1000 + migration-threshold: 5000 - ha_cluster_hacluster_password: + sap_ha_pacemaker_cluster_host_type: + type: list + choices: +# - hana_scaleup_costopt + - hana_scaleup_perf +# - hana_scaleup_perf_dr +# - hana_scaleout + - nwas_abap_ascs_ers +# - nwas_abap_pas_aas +# - nwas_java_scs_ers + default: hana_scaleup_perf description: - - The password of the `hacluster` user which is created during pacemaker installation. - no_log: true - required: true - type: str + - The SAP landscape to for which the cluster is to be configured. + - The default is a 2-node SAP HANA scale-up cluster. - sap_ha_pacemaker_cluster_aws_region: +# sap_ha_pacemaker_cluster_replication_type: +# choices: +# - mtr +# - none +# default: none +# description: +# - The type of SAP HANA site replication across multiple hosts. +# - _Not yet supported_ + + sap_ha_pacemaker_cluster_fence_options: + type: dict + default: + pcmk_reboot_retries: 4 + pcmk_reboot_timeout: 400 + power_timeout: 240 description: - - The AWS region in which the instances to be used for the cluster setup are located. - - Required for cluster nodes setup on Amazon cloud. - required: false - type: str + - STONITH resource common parameters that apply to most fencing agents. + - These options are applied to fencing resources this role uses automatically for pre-defined platforms (like AWS EC2 VS, IBM Cloud VS). + - The listed options are set by default. + - Additional options can be added by defining this parameter in dictionary format and adding the defaults plus any valid stonith resource key-value pair. - sap_ha_pacemaker_cluster_aws_access_key_id: + example: + sap_ha_pacemaker_cluster_fence_options: + pcmk_reboot_retries: 4 + pcmk_reboot_timeout: 400 + power_timeout: 240 + + + sap_ha_pacemaker_cluster_vip_client_interface: description: - - AWS access key to allow control of instances (for example for fencing operations). - - Required for cluster nodes setup on Amazon cloud. - required: false - type: str + - OS device name of the network interface to use for the Virtual IP configuration. + - When there is only one interface on the system, its name will be used by default. - sap_ha_pacemaker_cluster_aws_secret_access_key: + sap_ha_pacemaker_cluster_stonith_custom: + type: list description: - - AWS secret key, paired with the access key for instance control. - - Required for cluster nodes setup on Amazon cloud. - required: false - type: str + - Custom list of STONITH resource(s) to be configured in the cluster. + - This definition override any defaults the role would apply otherwise. + elements: dict + options: + name: + description: + - Name that will be used as the resource ID (name). + required: true + agent: + description: + - Resource agent name, must contain the prefix "stonith:" to avoid mismatches or failures. + required: true + options: + description: + - The resource options listed in dictionary format, one option per line. + - Requires the mandatory options for the particular stonith resource agent to be defined, otherwise the setup will fail. + required: true + + example: + sap_ha_pacemaker_cluster_stonith_custom: + - name: "my-fence-resource" + agent: "stonith:fence_rhevm" + options: + ip: rhevm-server + username: login-user + password: login-user-password + pcmk_host_list: node1,node2 + power_wait: 3 sap_ha_pacemaker_cluster_cluster_properties: - default: See example + type: dict + default: + stonith-enabled: true + stonith-timeout: 900 + concurrent-fencing: true description: - Standard pacemaker cluster properties are configured with recommended settings for cluster node fencing. + - When no STONITH resource is defined, STONITH will be disabled and a warning displayed. + example: sap_ha_pacemaker_cluster_cluster_properties: stonith-enabled: true stonith-timeout: 900 concurrent-fencing: true - required: false + + ########################################################################## + # Parameters that are optionally imported from 'ha_cluster' LSR parameters + ########################################################################## + + sap_ha_pacemaker_cluster_ha_cluster: type: dict + description: + - The `ha_cluster` LSR native parameter `ha_cluster` can be used as a synonym. + - Optional _**host_vars**_ parameter - if defined it must be set for each node. + - Dictionary that can contain various node options for the pacemaker cluster configuration. + - Supported options can be reviewed in the `ha_cluster` Linux System Role [https://github.com/linux-system-roles/ha_cluster/blob/master/README.md]. + - If not defined, the `ha_cluster` Linux System Role default will be used. - sap_ha_pacemaker_cluster_create_config_dest: - default: _resource_config.yml + example: + sap_ha_pacemaker_cluster_ha_cluster: + corosync_addresses: + - 192.168.1.10 + - 192.168.2.10 + node_name: nodeA + + + sap_ha_pacemaker_cluster_cluster_name: description: - - The pacemaker cluster resource configuration optionally created by this role will be saved in a Yaml file in the current working directory. - - Requires `sap_ha_pacemaker_cluster_create_config_varfile` to be enabled for generating the output file. - - Specify a path/filename to save the file in a custom location. - - The file can be used as input vars file for an Ansible playbook running the 'ha_cluster' Linux System Role. - required: false - type: str + - The name of the pacemaker cluster. + - Inherits the `ha_cluster` LSR native parameter `ha_cluster_cluster_name` if not defined. + - If not defined, the `ha_cluster` Linux System Role default will be used. - sap_ha_pacemaker_cluster_create_config_varfile: - default: false + sap_ha_pacemaker_cluster_extra_packages: + type: list description: - - When enabled, all cluster configuration parameters this role constructs for executing the 'ha_cluster' Linux System role will be written into a file in Yaml format. - - This allows using the output file later as input file for additional custom steps using the 'ha_cluster' role and covering the resource configuration in a cluster that was set up using this 'sap_ha_pacemaker_cluster' role. - - When enabled this parameters file is also created when the playbook is run in check_mode (`--check`) and can be used to review the configuration parameters without executing actual changes on the target nodes. - - WARNING! This report may include sensitive details like secrets required for certain cluster resources! - required: false - type: bool + - Additional extra packages to be installed, for instance specific resource packages. + - For SAP clusters configured by this role, the relevant standard packages for the target scenario are automatically included. - sap_ha_pacemaker_cluster_fence_options: + sap_ha_pacemaker_cluster_fence_agent_packages: + type: list description: - - STONITH resource common parameters that apply to most fencing agents. - - These options are applied to fencing resources this role uses automatically for pre-defined platforms (like AWS EC2 VS, IBM Cloud VS). - - The listed options are set by default. - - Additional options can be added by defining this parameter in dictionary format and adding the defaults plus any valid stonith resource key-value pair. + - Additional fence agent packages to be installed. + - This is automatically combined with `sap_ha_pacemaker_cluster_fence_agent_minimal_packages`. - example: - sap_ha_pacemaker_cluster_fence_options: - pcmk_reboot_retries: 4 - pcmk_reboot_timeout: 400 - power_timeout: 240 + sap_ha_pacemaker_cluster_hacluster_user_password: + description: + - The password of the `hacluster` user which is created during pacemaker installation. + - Inherits the value of `ha_cluster_hacluster_password`, when defined. + no_log: true + required: true - required: false - type: dict + + ########################################################################## + # HANA specific parameters + ########################################################################## + + sap_ha_pacemaker_cluster_hana_sid: + description: + - The SAP HANA SID of the instance that will be configured in the cluster. + - The SID must follow SAP specifications - see SAP Note 1979280. + - Inherits the value of `sap_hana_sid`, when defined. + - Mandatory for SAP HANA cluster setups. + + sap_ha_pacemaker_cluster_hana_instance_nr: + description: + - The instance number of the SAP HANA database which this role will configure in the cluster. + - Inherits the value of `sap_hana_instance_number`, when defined. + - Mandatory for SAP HANA cluster setups. sap_ha_pacemaker_cluster_hana_automated_register: + type: bool default: true description: - Parameter for the 'SAPHana' cluster resource. - Define if a former primary should be re-registered automatically as secondary. - required: false - type: bool sap_ha_pacemaker_cluster_hana_duplicate_primary_timeout: + type: int default: 900 description: - Parameter for the 'SAPHana' cluster resource. - Time difference needed between to primary time stamps, if a dual-primary situation occurs. - If the time difference is less than the time gap, then the cluster holds one or both instances in a "WAITING" status. - This is to give an admin a chance to react on a failover. A failed former primary will be registered after the time difference is passed. - required: false - type: int sap_ha_pacemaker_cluster_hana_prefer_site_takeover: + type: bool choices: - true - false @@ -153,170 +297,389 @@ argument_specs: - Parameter for the 'SAPHana' cluster resource. - Set to "false" if the cluster should first attempt to restart the instance on the same node. - When set to "true" (default) a failover to secondary will be initiated on resource failure. - required: false - type: bool sap_ha_pacemaker_cluster_hana_resource_name: default: "SAPHana__" description: - Customize the cluster resource name of the SAP HANA DB resource. - required: false - type: str + + sap_ha_pacemaker_cluster_hana_resource_clone_name: + default: "SAPHana__-clone" + description: + - Customize the cluster resource name of the SAP HANA DB resource clone. sap_ha_pacemaker_cluster_hana_topology_resource_name: default: "SAPHanaTopology__" description: - Customize the cluster resource name of the SAP HANA Topology resource. - required: false - type: str - sap_ha_pacemaker_cluster_ibmcloud_api_key: + sap_ha_pacemaker_cluster_hana_topology_resource_clone_name: + default: "SAPHanaTopology__-clone" description: - - The API key is required to allow control of instances (for example for fencing operations). - - Required for cluster nodes setup in IBM Cloud. - required: false - type: str + - Customize the cluster resource name of the SAP HANA Topology resource clone. - sap_ha_pacemaker_cluster_ibmcloud_region: + sap_ha_pacemaker_cluster_vip_hana_primary_ip_address: description: - - The cloud region key in which the instances are running. - - Required for cluster nodes setup in IBM Cloud. - required: false - type: str + - The virtual IP of the primary HANA instance. + - Mandatory parameter for HANA clusters. - sap_ha_pacemaker_cluster_replication_type: - choices: - - mtr - - none - default: none + sap_ha_pacemaker_cluster_vip_hana_primary_resource_name: + default: "vip_" description: - - The type of SAP HANA site replication across multiple hosts. - - _Not yet supported_ - required: false - type: str + - Customize the name of the resource managing the Virtual IP of the primary HANA instance. - sap_ha_pacemaker_cluster_resource_defaults: - default: See example + sap_ha_pacemaker_cluster_vip_hana_secondary_ip_address: description: - - Set default parameters that will be valid for all pacemaker resources. + - The virtual IP for read-only access to the secondary HANA instance. + - Optional parameter in HANA clusters. + + sap_ha_pacemaker_cluster_vip_secondary_resource_name: + default: "vip_" + description: + - Customize the name of the resource managing the Virtual IP of read-only access to the secondary HANA instance. + + + ########################################################################## + # NetWeaver specific parameters + ########################################################################## + + sap_ha_pacemaker_cluster_nwas_abap_ascs_ers_ensa1: + type: bool + default: false + description: + - The standard NetWeaver ASCS/ERS cluster will be set up as ENSA2. + - Set this parameter to 'true' to configure it as ENSA1. + + sap_ha_pacemaker_cluster_enable_cluster_connector: + type: bool + default: true + description: + - Enables/Disables the SAP HA Interface for SAP ABAP application server instances, also known as `sap_cluster_connector`. + - Set this parameter to 'false' if the SAP HA interface should not be installed and configured. + + sap_ha_pacemaker_cluster_nwas_abap_sid: + description: + - SID of the NetWeaver instances. + - Mandatory for NetWeaver cluster configuration. + - Uses `sap_swpm_sid` if defined. + - Mandatory for NetWeaver cluster setups. + + sap_ha_pacemaker_cluster_nwas_abap_ascs_instance_nr: + description: + - Instance number of the NetWeaver ABAP ASCS instance. + - Mandatory for NetWeaver ASCS/ERS cluster configuration. + + sap_ha_pacemaker_cluster_nwas_abap_ers_instance_nr: + description: + - Instance number of the NetWeaver ABAP ERS instance. + - Mandatory for NetWeaver ASCS/ERS cluster configuration. + + sap_ha_pacemaker_cluster_nwas_abap_pas_instance_nr: + description: + - Instance number of the NetWeaver ABAP PAS instance. + - Mandatory for NetWeaver PAS cluster configuration. + + sap_ha_pacemaker_cluster_nwas_abap_aas_instance_nr: + description: + - Instance number of the NetWeaver ABAP AAS instance. + - Mandatory for NetWeaver AAS cluster configuration. + + sap_ha_pacemaker_cluster_storage_definition: + type: list + description: + - List of filesystem definitions used for filesystem cluster resources. + - Options relevant, see example. + - Mandatory for SAP NetWeaver HA cluster configurations. + - Reuse `sap_storage_setup_definition` if defined. + - Reuse `sap_storage_setup_definition` will extract values 'mountpoint', 'nfs_filesystem_type', 'nfs_mount_options', 'nfs_path', 'nfs_server'. + - Reuse `sap_storage_setup_definition` all options are documented under Ansible Role `sap_storage_setup`. + - Note! For this variable, the argument specification does not list options, to avoid errors during reuse of `sap_storage_setup_definition` if defined. + elements: dict + example: - sap_ha_pacemaker_cluster_resource_defaults: - resource-stickiness: 1000 - migration-threshold: 5000 + sap_ha_pacemaker_cluster_storage_definition: + - name: usr_sap + mountpoint: /usr/sap + nfs_path: /usr/sap + nfs_server: "nfs-server.example.com:/" + - name: usr_sap_trans + mountpoint: /usr/sap/trans + nfs_path: /usr/sap/trans + nfs_server: "nfs-server.example.com:/" + - name: sapmnt + mountpoint: /sapmnt + nfs_filesystem_type: nfs + nfs_mount_options: defaults + nfs_path: /sapmnt + nfs_server: "nfs-server.example.com:/" + + + sap_ha_pacemaker_cluster_storage_nfs_filesytem_type: + default: nfs + description: + - Filesystem type of the NFS filesystems that are part of the cluster configuration. - required: false - type: dict + sap_ha_pacemaker_cluster_storage_nfs_mount_options: + default: defaults + description: + - Mount options of the NFS filesystems that are part of the cluster configuration. -# sap_ha_pacemaker_cluster_host_type: -# choices: -## - hana_scaleup_costopt -# - hana_scaleup_perf -## - hana_scaleup_perf_dr -## - hana_scaleout -# - nwas_abap_ascs_ers -# - nwas_abap_pas_aas -## - nwas_java_scs_ers -# default: hana_scaleup_perf -# description: -# - The SAP landscape to be installed. -# required: false -# type: str + sap_ha_pacemaker_cluster_storage_nfs_server: + description: + - Default address of the NFS server, if not defined individually by filesystem. - sap_ha_pacemaker_cluster_vip_client_interface: - default: eth0 + sap_ha_pacemaker_cluster_vip_nwas_abap_ascs_ip_address: description: - - OS device name of the network interface to use for the Virtual IP configuration. - - This is used for VIP agents that require an interface name, for example in cloud platform environments. - required: false - type: str + - Virtual IP of the NetWeaver ASCS instance. + - Mandatory for NetWeaver ASCS/ERS cluster setup. + + sap_ha_pacemaker_cluster_vip_nwas_abap_ascs_resource_name: + default: vip___ascs + description: + - Name of the SAPInstance resource for NetWeaver ASCS. + + sap_ha_pacemaker_cluster_vip_nwas_abap_ers_ip_address: + description: + - Virtual IP of the NetWeaver ERS instance. + - Mandatory for NetWeaver ASCS/ERS cluster setup. + + sap_ha_pacemaker_cluster_vip_nwas_abap_ers_resource_name: + default: vip___ers + description: + - Name of the SAPInstance resource for NetWeaver ERS. + + sap_ha_pacemaker_cluster_vip_nwas_abap_pas_ip_address: + description: + - Virtual IP of the NetWeaver PAS instance. + - Mandatory for NetWeaver PAS cluster setup. + + sap_ha_pacemaker_cluster_vip_nwas_abap_pas_resource_name: + default: vip___pas + description: + - Name of the SAPInstance resource for NetWeaver PAS. + + sap_ha_pacemaker_cluster_vip_nwas_abap_aas_ip_address: + description: + - Virtual IP of the NetWeaver AAS instance. + - Mandatory for NetWeaver AAS cluster setup. + + sap_ha_pacemaker_cluster_vip_nwas_abap_aas_resource_name: + default: vip___aas + description: + - Name of the SAPInstance resource for NetWeaver AAS. + + sap_ha_pacemaker_cluster_nwas_sapmnt_filesystem_resource_name: + default: Filesystem_NWAS_SAPMNT_ + description: + - Filesystem resource name for the shared filesystem /sapmnt. + - Optional, this is typically managed by the OS, but can as well be added to the cluster configuration. + - Enable this resource setup using `sap_ha_pacemaker_cluster_nwas_shared_filesystems_cluster_managed`. + + sap_ha_pacemaker_cluster_nwas_transports_filesystem_resource_name: + default: Filesystem_NWAS_TRANS_ + description: + - Filesystem resource name for the transports filesystem /usr/sap/trans. + - Optional, this is typically managed by the OS, but can as well be added to the cluster configuration. + - Enable this resource setup using `sap_ha_pacemaker_cluster_nwas_shared_filesystems_cluster_managed`. + + sap_ha_pacemaker_cluster_nwas_sys_filesystem_resource_name: + default: Filesystem_NWAS_SYS_ + description: + - Filesystem resource name for the transports filesystem /usr/sap//SYS. + - Optional, this is typically managed by the OS, but can as well be added to the cluster configuration. + - Enable this resource setup using `sap_ha_pacemaker_cluster_nwas_shared_filesystems_cluster_managed`. + + sap_ha_pacemaker_cluster_nwas_shared_filesystems_cluster_managed: + type: bool + default: false + description: + - Change this parameter to 'true' if the 3 shared filesystems `/usr/sap/trans`, `/usr/sap//SYS` and '/sapmnt' shall be configured as cloned cluster resources. + + + ########################################################################## + # NetWeaver ASCS specific parameters + ########################################################################## + + sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_instance_name: + description: + - The name of the ASCS instance, typically the profile name. + - Mandatory for the NetWeaver ASCS/ERS cluster setup + + sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_start_profile_string: + description: + - The full path and name of the ASCS instance profile. + - Mandatory for the NetWeaver ASCS/ERS cluster setup. + + sap_ha_pacemaker_cluster_nwas_abap_ascs_filesystem_resource_name: + default: Filesystem_NWAS_ABAP_ASCS__ + description: + - Name of the filesystem resource for the ASCS instance. + + sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_resource_name: + default: SAPInstance_NWAS_ABAP_ASCS__ + description: + - Name of the ASCS instance resource. + + sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_automatic_recover_bool: + type: bool + default: false + description: + - NetWeaver ASCS instance resource option "AUTOMATIC_RECOVER". + + sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_resource_stickiness: + default: 5000 + description: + - NetWeaver ASCS instance resource stickiness attribute. + + sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_ensa1_migration_threshold: + default: 1 + description: + - NetWeaver ASCS instance migration-threshold setting attribute. + - Only used for ENSA1 setups (see `sap_ha_pacemaker_cluster_nwas_abap_ascs_ers_ensa1`). Default setup is ENSA2. + + sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_ensa1_failure_timeout: + default: 60 + description: + - NetWeaver ASCS instance failure-timeout attribute. + - Only used for ENSA1 setups (see `sap_ha_pacemaker_cluster_nwas_abap_ascs_ers_ensa1`). Default setup is ENSA2. - sap_ha_pacemaker_cluster_vip_resource_name: - default: "vip__" + sap_ha_pacemaker_cluster_nwas_abap_ascs_group_stickiness: + default: 3000 description: - - Customize the name of the resource managing the Virtual IP. - required: false - type: str + - NetWeaver ASCS resource group stickiness to prefer the ASCS group to stay on the node it was started on. - sap_ha_pacemaker_cluster_vip_update_rt: + + ########################################################################## + # NetWeaver ERS specific parameters + ########################################################################## + + sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_instance_name: + description: + - The name of the ERS instance, typically the profile name. + - Mandatory for the NetWeaver ASCS/ERS cluster setup. + + sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_start_profile_string: + description: + - The full path and name of the ERS instance profile. + - Mandatory for the NetWeaver ASCS/ERS cluster. + + sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_automatic_recover_bool: + type: bool + default: false + description: + - NetWeaver ERS instance resource option "AUTOMATIC_RECOVER". + + sap_ha_pacemaker_cluster_nwas_abap_ers_filesystem_resource_name: + default: Filesystem_NWAS_ABAP_ERS__ + description: + - Name of the filesystem resource for the ERS instance. + + sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_resource_name: + default: SAPInstance_NWAS_ABAP_ERS__ + description: + - Name of the ERS instance resource. + + + ########################################################################## + # PAS specific parameters + ########################################################################## + + # TODO: implement PAS cluster setup + + ########################################################################## + # PAS specific parameters + ########################################################################## + + # TODO: implement AAS cluster setup + + + ########################################################################## + # Platforms: AWS specific parameters + ########################################################################## + + sap_ha_pacemaker_cluster_aws_vip_update_rt: description: - List one more routing table IDs for managing Virtual IP failover through routing table changes. - - Required for VIP configuration in AWS EC2 environments. - required: false - type: list + - Multiple routing tables must be defined as a comma-separated string (no spaces). + - Mandatory for the VIP resource configuration in AWS EC2 environments. - sap_hana_cluster_nodes: + sap_ha_pacemaker_cluster_aws_region: description: - - List of cluster nodes and associated attributes to describe the target SAP HA environment. - - This is required for the HANA System Replication configuration. + - The AWS region in which the instances to be used for the cluster setup are located. + - Mandatory for cluster nodes setup on AWS EC2 instances. - example: - sap_hana_cluster_nodes: - - node_name: nodeA - node_role: primary - hana_site: DC01 - node_ip: 192.168.5.1 - - node_name: nodeB - node_role: secondary - hana_site: DC02 - node_ip: 192.168.5.2 + sap_ha_pacemaker_cluster_aws_access_key_id: + description: + - AWS access key to allow control of instances (for example for fencing operations). + - Mandatory for the cluster nodes setup on AWS EC2 instances. + + sap_ha_pacemaker_cluster_aws_secret_access_key: + description: + - AWS secret key, paired with the access key for instance control. + - Mandatory for the cluster setup on AWS EC2 instances. - elements: dict - required: false - type: list - options: - node_ip: - description: - - IP address of the node used for HANA System Replication. - required: true - node_name: - description: - - Name of the cluster node, should match the remote systems' hostnames. - - This is needed by the cluster members to know all their partner nodes. - required: true - node_role: - choices: - - primary - - secondary - description: - - Role of this node in the SAP cluster setup. - - There must be only **one** primary, but there can be multiple secondary nodes. - required: true - hana_site: - description: - - Site of the cluster and/or SAP HANA System Replication node (for example 'DC01'). - - This is required for HANA System Replication configuration. - required: true - sap_hana_instance_number: + ########################################################################## + # Platforms: GCP specific parameters + ########################################################################## + + sap_ha_pacemaker_cluster_gcp_project: description: - - The instance number of the SAP HANA database which is role will configure in the cluster. - required: true - type: str + - Google Cloud project name in which the target instances are installed. + - Mandatory for the cluster setup on GCP instances. - sap_hana_sid: + sap_ha_pacemaker_cluster_gcp_region_zone: description: - - The SAP HANA SID of the instance that will be configured in the cluster. - - The SID must follow SAP specifications - see SAP Note 1979280. - required: false - type: str + - Google Cloud Platform region zone ID. + - Mandatory for the cluster setup on GCP instances. + - sap_hana_vip: + ########################################################################## + # Platforms: IBM Cloud specific parameters - VS and Power VS common + ########################################################################## + + sap_ha_pacemaker_cluster_ibmcloud_api_key: description: - - One floating IP is required for SAP HANA DB connection by clients. - - This main VIP will always run on the promoted HANA node and be moved with it during a failover. + - The API key which is required to allow the control of instances (for example for fencing operations). + - Mandatory for the cluster setup on IBM Cloud Virtual Server instances or IBM Power Virtual Server on IBM Cloud. - example: - sap_hana_vip: - primary: 192.168.10.100 + sap_ha_pacemaker_cluster_ibmcloud_region: + description: + - The IBM Cloud VS region name in which the instances are running. + - Mandatory for the cluster setup on IBM Cloud Virtual Server instances or IBM Power Virtual Server on IBM Cloud. - required: false - type: dict - required_one_of: [{ primary, main, rw, promoted }] -# TODO: review the global parameter vs. role parameter logic and compatibility of combination of HANA + NW -# sap_system_sid: -# description: -# - The SID of the SAP Netweaver system that will be configured in the cluster. -# - The SID must follow SAP specifications - see SAP Note 1979280. -# required: false -# type: str + ########################################################################## + # Platforms: IBM Power VS on IBM Cloud specific parameters + ########################################################################## + + sap_ha_pacemaker_cluster_ibmcloud_powervs_workspace_crn: + description: + - IBM Power Virtual Server Workspace service cloud resource name (CRN) identifier which contains the target instances + - Mandatory for the cluster setup on IBM Power Virtual Server from IBM Cloud. + + sap_ha_pacemaker_cluster_ibmcloud_powervs_api_type: + description: + - IBM Power Virtual Server API Endpoint type (public or private) dependent on network interface attachments for the target instances. + - - Mandatory for the cluster setup on IBM Power Virtual Server from IBM Cloud. + + sap_ha_pacemaker_cluster_ibmcloud_powervs_forward_proxy_url: + description: + - IBM Power Virtual Server forward proxy url when IBM Power Virtual Server API Endpoint type is set to private. + - When public network interface, can be ignored. + - When private network interface, mandatory for the cluster setup on IBM Power Virtual Server from IBM Cloud. + + + ########################################################################## + # Platforms: MS Azure specific parameters + ########################################################################## + + sap_ha_pacemaker_cluster_msazure_subscription_id: + description: + - Subscription ID of the MS Azure environment containing the target instances. + - Mandatory for the cluster setup on MS Azure instances. + + sap_ha_pacemaker_cluster_msazure_resource_group: + description: + - Resource group name/ID in which the target instances are defined. + - Mandatory for the cluster setup on MS Azure instances. diff --git a/roles/sap_ha_pacemaker_cluster/tasks/ascertain_ha_cluster_in_inventory.yml b/roles/sap_ha_pacemaker_cluster/tasks/ascertain_ha_cluster_in_inventory.yml deleted file mode 100644 index 408bb89e6..000000000 --- a/roles/sap_ha_pacemaker_cluster/tasks/ascertain_ha_cluster_in_inventory.yml +++ /dev/null @@ -1,54 +0,0 @@ ---- -# If there are "ha_cluster" linux system role parameters already defined in the -# inventory, we will include these custom specifications. - -### Take the following template to add additional parameters to be inherited: -# - name: "SAP HA Prepare Pacemaker - Register ha_cluster_" -# ansible.builtin.set_fact: -# __sap_ha_pacemaker_cluster_: "{{ ha_cluster_ }}" -# when: ha_cluster_ is defined - -- name: "SAP HA Prepare Pacemaker - Register ha_cluster_cluster_properties" - when: ha_cluster_cluster_properties is defined - ansible.builtin.set_fact: - __sap_ha_pacemaker_cluster_cluster_properties: "{{ ha_cluster_cluster_properties }}" - -- name: "SAP HA Prepare Pacemaker - Register ha_cluster_constraints_colocation" - when: ha_cluster_constraints_colocation is defined - ansible.builtin.set_fact: - __sap_ha_pacemaker_cluster_constraints_colocation: "{{ ha_cluster_constraints_colocation }}" - -- name: "SAP HA Prepare Pacemaker - Register ha_cluster_constraints_location" - when: ha_cluster_constraints_location is defined - ansible.builtin.set_fact: - __sap_ha_pacemaker_cluster_constraints_location: "{{ ha_cluster_constraints_location }}" - -- name: "SAP HA Prepare Pacemaker - Register ha_cluster_constraints_order" - when: ha_cluster_constraints_order is defined - ansible.builtin.set_fact: - __sap_ha_pacemaker_cluster_constraints_order: "{{ ha_cluster_constraints_order }}" - -- name: "SAP HA Prepare Pacemaker - Register ha_cluster_fence_agent_packages" - when: ha_cluster_fence_agent_packages is defined - ansible.builtin.set_fact: - __sap_ha_pacemaker_cluster_fence_agent_packages: "{{ ha_cluster_fence_agent_packages }}" - -- name: "SAP HA Prepare Pacemaker - Register ha_cluster_repos" - when: ha_cluster_repos is defined - ansible.builtin.set_fact: - __sap_ha_pacemaker_cluster_repos: "{{ ha_cluster_repos }}" - -- name: "SAP HA Prepare Pacemaker - Register ha_cluster_resource_clones" - when: ha_cluster_resource_clones is defined - ansible.builtin.set_fact: - __sap_ha_pacemaker_cluster_resource_clones: "{{ ha_cluster_resource_clones }}" - -- name: "SAP HA Prepare Pacemaker - Register ha_cluster_resource_groups" - when: ha_cluster_resource_groups is defined - ansible.builtin.set_fact: - __sap_ha_pacemaker_cluster_resource_groups: "{{ ha_cluster_resource_groups }}" - -- name: "SAP HA Prepare Pacemaker - Register ha_cluster_resource_primitives" - when: ha_cluster_resource_primitives is defined - ansible.builtin.set_fact: - __sap_ha_pacemaker_cluster_resource_primitives: "{{ ha_cluster_resource_primitives }}" diff --git a/roles/sap_ha_pacemaker_cluster/tasks/ascertain_sap_landscape.yml b/roles/sap_ha_pacemaker_cluster/tasks/ascertain_sap_landscape.yml index aa4afc90b..b6bdaaa58 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/ascertain_sap_landscape.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/ascertain_sap_landscape.yml @@ -10,12 +10,12 @@ # 2 nodes are also valid for other scenarios. # TODO: collect possible rules for target landscapes -- name: SAP HA Prepare Pacemaker - Fail if there is only 1 target host +- name: "SAP HA Prepare Pacemaker - Fail if there is only 1 target host" ansible.builtin.assert: that: - ansible_play_hosts | length > 1 -- name: SAP HA Prepare Pacemaker - Make sure the 'type' parameter is a list +- name: "SAP HA Prepare Pacemaker - Make sure the 'type' parameter is a list" ansible.builtin.set_fact: sap_ha_pacemaker_cluster_host_type: | {% if sap_ha_pacemaker_cluster_host_type | type_debug != 'list' -%} @@ -24,21 +24,21 @@ {{ sap_ha_pacemaker_cluster_host_type }} {%- endif %} -- name: SAP HA Prepare Pacemaker - Verify that for 'hana_scaleup' types 2 nodes are used +- name: "SAP HA Prepare Pacemaker - Verify that for 'hana_scaleup' types 2 nodes are used" ansible.builtin.assert: that: - ansible_play_hosts | length == 2 when: - - "'hana_scaleup' in sap_ha_pacemaker_cluster_host_type[0]" + - sap_ha_pacemaker_cluster_host_type | select('search', 'hana_scaleup') | length > 0 -- name: SAP HA Prepare Pacemaker - Include HANA specific variables +- name: "SAP HA Prepare Pacemaker - Include HANA specific variables" ansible.builtin.include_tasks: file: include_vars_hana.yml when: - - "'hana' in sap_ha_pacemaker_cluster_host_type[0]" + - sap_ha_pacemaker_cluster_host_type | select('search', 'hana_scaleup') | length > 0 -- name: SAP HA Prepare Pacemaker - Include NETWEAVER specific variables +- name: "SAP HA Prepare Pacemaker - Include NETWEAVER specific variables" ansible.builtin.include_tasks: - file: include_vars_netweaver.yml + file: include_vars_nwas.yml when: - - "'nwas' in sap_ha_pacemaker_cluster_host_type[0]" + - sap_ha_pacemaker_cluster_host_type | select('search', 'nwas') | length > 0 diff --git a/roles/sap_ha_pacemaker_cluster/tasks/configure_nwas_ascs_ers_postinstallation.yml b/roles/sap_ha_pacemaker_cluster/tasks/configure_nwas_ascs_ers_postinstallation.yml new file mode 100644 index 000000000..08681b6f0 --- /dev/null +++ b/roles/sap_ha_pacemaker_cluster/tasks/configure_nwas_ascs_ers_postinstallation.yml @@ -0,0 +1,207 @@ +--- +# After NetWeaver ASCS/ERS instances were configured in the cluster, +# they must be disabled from automatically (re)starting outside of +# cluster control. + +- name: "SAP HA Pacemaker - (ASCS profile) Prevent automatic restart of enqueue server" + ansible.builtin.replace: + path: "{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_start_profile_string }}" + backup: true + regexp: 'Restart_Program_01' + replace: 'Start_Program_01' + +- name: "SAP HA Pacemaker - (ERS profile) Prevent automatic restart" + ansible.builtin.replace: + path: "{{ sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_start_profile_string }}" + backup: true + regexp: 'Restart_Program_00' + replace: 'Start_Program_00' + +# Comment out lines in /usr/sap/sapservices, which +# - contain the target instance profile names +# - are not commented out yet +- name: "SAP HA Pacemaker - Update /usr/sap/sapservices" + ansible.builtin.replace: + path: /usr/sap/sapservices + backup: true + regexp: '^([^#\n].+{{ sapserv_item }}.+)$' + replace: '# \1' + loop: + - "{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_instance_name }}" + - "{{ sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_instance_name }}" + loop_control: + loop_var: sapserv_item + +- name: "SAP HA Pacemaker - (systemd) Check for ASCS/ERS services" + ansible.builtin.stat: + path: "/etc/systemd/system/SAP{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_{{ systemd_item }}.service" + loop: + - "{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_instance_nr }}" + - "{{ sap_ha_pacemaker_cluster_nwas_abap_ers_instance_nr }}" + loop_control: + loop_var: systemd_item + label: "SAP{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_{{ systemd_item }}.service" + register: __sap_ha_pacemaker_cluster_register_instance_service + +- name: "SAP HA Pacemaker - (systemd) Save found ASCS/ERS services" + ansible.builtin.set_fact: + sap_ha_pacemaker_cluster_instance_services_fact: "{{ + __sap_ha_pacemaker_cluster_register_instance_service.results + | selectattr('stat.exists') + | map(attribute='stat.path') + | regex_replace('/etc/systemd/system/', '') + }}" + +# BLOCK: +# When the systemd based SAP startup framework is used, make sure that the +# instance services do not auto-start. +- name: "SAP HA Pacemaker - Block to disable systemd auto-start of instances" + when: + - sap_ha_pacemaker_cluster_instance_services_fact is defined + - sap_ha_pacemaker_cluster_instance_services_fact | length > 0 + block: + + - name: "SAP HA Pacemaker - (systemd) Disable ASCS/ERS instance service" + ansible.builtin.service: + name: "{{ instance_srv_item }}" + enabled: false + loop: "{{ sap_ha_pacemaker_cluster_instance_services_fact }}" + loop_control: + loop_var: instance_srv_item + + # Creates a config file for the services. + # Parent directories will be created when missing. + - name: "SAP HA Pacemaker - (systemd) Create ASCS/ERS instance unit config file" + ansible.builtin.lineinfile: + create: true + path: "/etc/systemd/system/{{ dropfile_item }}.d/HA.conf" + line: "[Service]" + owner: root + group: root + mode: '0644' + loop: "{{ sap_ha_pacemaker_cluster_instance_services_fact }}" + loop_control: + loop_var: dropfile_item + + - name: "SAP HA Pacemaker - (systemd) Disable ASCS/ERS instance unit auto-restart" + ansible.builtin.lineinfile: + path: "/etc/systemd/system/{{ dropfile_item }}.d/HA.conf" + regex: '^Restart\s*=\s*no' + insertafter: '^[Service]$' + line: "Restart=no" + owner: root + group: root + mode: '0644' + loop: "{{ sap_ha_pacemaker_cluster_instance_services_fact }}" + loop_control: + loop_var: dropfile_item + +### END of BLOCK for systemd setup. + + +# Block for configuring the SAP HA Interface (sap_cluster_connector). +# +# The 'sap-cluster-connector' package is already optionally added to +# '__sap_ha_pacemaker_cluster_sap_extra_packages'. +- name: "SAP HA Pacemaker - (SAP HA Interface) Configure SAP HA Interface" + when: + - sap_ha_pacemaker_cluster_enable_cluster_connector + block: + + - name: "SAP HA Pacemaker - (SAP HA Interface) Add {{sap_ha_pacemaker_cluster_nwas_abap_sid | lower }}adm user to 'haclient' group" + ansible.builtin.user: + name: "{{ sap_ha_pacemaker_cluster_nwas_abap_sid | lower }}adm" + groups: haclient + append: true + state: present + + # Using 'lineinfile' with a nested loop to avoid duplicate entries for existing configuration. + - name: "SAP HA Pacemaker - (SAP HA Interface) Add connector to start profiles" + ansible.builtin.lineinfile: + backup: true + path: "{{ nwas_profile_item.0 }}" + line: "{{ nwas_profile_item.1 }}" + loop: "{{ __sap_ha_pacemaker_cluster_nwas_abap_ascs_ers_profile_paths + | product(__sap_ha_pacemaker_cluster_connector_config_lines) + }}" + loop_control: + loop_var: nwas_profile_item + label: "{{ nwas_profile_item.0 }} -> {{ nwas_profile_item.1 }}" + + - name: "SAP HA Pacemaker - (SAP HA Interface) Wait for ASCS to be up and running" + become_user: "{{ sap_ha_pacemaker_cluster_nwas_abap_sid | lower }}adm" + register: __sap_ha_pacemaker_cluster_register_where_ascs + ansible.builtin.shell: | + /usr/sap/hostctrl/exe/sapcontrol -nr {{ sap_ha_pacemaker_cluster_nwas_abap_ascs_instance_nr }} -function WaitforStarted 600 15 + changed_when: false + failed_when: false + + - name: "SAP HA Pacemaker - (SAP HA Interface) Wait for ERS to be up and running" + become_user: "{{ sap_ha_pacemaker_cluster_nwas_abap_sid | lower }}adm" + register: __sap_ha_pacemaker_cluster_register_where_ers + ansible.builtin.shell: | + /usr/sap/hostctrl/exe/sapcontrol -nr {{ sap_ha_pacemaker_cluster_nwas_abap_ers_instance_nr }} -function WaitforStarted 600 15 + changed_when: false + failed_when: false + + - name: "SAP HA Pacemaker - (SAP HA Interface) Restart the ASCS service" + when: + - __sap_ha_pacemaker_cluster_register_where_ascs.rc == 0 + become_user: "{{ sap_ha_pacemaker_cluster_nwas_abap_sid | lower }}adm" + register: __sap_ha_pacemaker_cluster_register_restart_ascs + ansible.builtin.shell: | + /usr/sap/hostctrl/exe/sapcontrol -nr {{ sap_ha_pacemaker_cluster_nwas_abap_ascs_instance_nr }} -function RestartService + changed_when: __sap_ha_pacemaker_cluster_register_restart_ascs.rc == 0 + + - name: "SAP HA Pacemaker - (SAP HA Interface) Restart the ERS service" + when: + - __sap_ha_pacemaker_cluster_register_where_ers.rc == 0 + become_user: "{{ sap_ha_pacemaker_cluster_nwas_abap_sid | lower }}adm" + register: __sap_ha_pacemaker_cluster_register_restart_ers + ansible.builtin.shell: | + /usr/sap/hostctrl/exe/sapcontrol -nr {{ sap_ha_pacemaker_cluster_nwas_abap_ers_instance_nr }} -function RestartService + changed_when: __sap_ha_pacemaker_cluster_register_restart_ers.rc == 0 + + - name: "SAP HA Pacemaker - (SAP HA Interface) Pause after service restart" + when: + - __sap_ha_pacemaker_cluster_register_restart_ascs.changed + or __sap_ha_pacemaker_cluster_register_restart_ers.changed + ansible.builtin.pause: + seconds: 10 + + - name: "SAP HA Pacemaker - (SAP HA Interface) Run HA check for ASCS" + when: + - __sap_ha_pacemaker_cluster_register_where_ascs.rc == 0 + become_user: "{{ sap_ha_pacemaker_cluster_nwas_abap_sid | lower }}adm" + register: __sap_ha_pacemaker_cluster_register_ascs_ha + ansible.builtin.shell: | + /usr/sap/hostctrl/exe/sapcontrol -nr {{ sap_ha_pacemaker_cluster_nwas_abap_ascs_instance_nr }} -function HACheckConfig + changed_when: false + + - name: "SAP HA Pacemaker - (SAP HA Interface) Run HA check for ERS" + when: + - __sap_ha_pacemaker_cluster_register_where_ers.rc == 0 + become_user: "{{ sap_ha_pacemaker_cluster_nwas_abap_sid | lower }}adm" + register: __sap_ha_pacemaker_cluster_register_ers_ha + ansible.builtin.shell: | + /usr/sap/hostctrl/exe/sapcontrol -nr {{ sap_ha_pacemaker_cluster_nwas_abap_ers_instance_nr }} -function HACheckConfig + changed_when: false + + - name: "SAP HA Pacemaker - (SAP HA Interface) Display HA check results for ASCS" + when: + - __sap_ha_pacemaker_cluster_register_where_ascs.rc == 0 + ansible.builtin.debug: + msg: | + {{ __sap_ha_pacemaker_cluster_register_ascs_ha.stdout }} + + - name: "SAP HA Pacemaker - (SAP HA Interface) Display HA check results for ERS" + when: + - __sap_ha_pacemaker_cluster_register_where_ers.rc == 0 + ansible.builtin.debug: + msg: | + {{ __sap_ha_pacemaker_cluster_register_ers_ha.stdout }} + + + # TODO: verification checks that the instances are running and HA Interface is enabled + +### END of BLOCK for sap_cluster_connector. diff --git a/roles/sap_ha_pacemaker_cluster/tasks/construct_final_hacluster_vars.yml b/roles/sap_ha_pacemaker_cluster/tasks/construct_final_hacluster_vars.yml new file mode 100644 index 000000000..a919561a4 --- /dev/null +++ b/roles/sap_ha_pacemaker_cluster/tasks/construct_final_hacluster_vars.yml @@ -0,0 +1,95 @@ +--- +# After all of the previous construction flows, the final parameters must +# be translated to 'ha_cluster' Linux System Role syntax. +# +# This way the include_role parameters are set as play vars and do not +# require a static list of vars when the role is included. + +# List of parameters that are constructed by this role, but not all of them +# are mandatory to be defined. For any undefined parameter the default of the +# 'ha_cluster' role will apply, if the role has a default defined. +# +# Make sure to always define those parameters which have no 'ha_cluster' LSR default! +# +# SAP HA Pacemaker Cluster role -> 'ha_cluster' Linux System Role +# ------------------------------------------------------------------------------ +# __sap_ha_pacemaker_cluster_ha_cluster ha_cluster +# __sap_ha_pacemaker_cluster_cluster_name ha_cluster_cluster_name +# __sap_ha_pacemaker_cluster_cluster_properties ha_cluster_cluster_properties +# __sap_ha_pacemaker_cluster_constraints_colocation ha_cluster_constraints_colocation +# __sap_ha_pacemaker_cluster_constraints_location ha_cluster_constraints_location +# __sap_ha_pacemaker_cluster_constraints_order ha_cluster_constraints_order +# __sap_ha_pacemaker_cluster_extra_packages ha_cluster_extra_packages +# __sap_ha_pacemaker_cluster_fence_agent_packages ha_cluster_fence_agent_packages +# __sap_ha_pacemaker_cluster_hacluster_user_password ha_cluster_hacluster_password +# __sap_ha_pacemaker_cluster_repos __ha_cluster_repos +# __sap_ha_pacemaker_cluster_resource_clones ha_cluster_resource_clones +# __sap_ha_pacemaker_cluster_resource_groups ha_cluster_resource_groups +# __sap_ha_pacemaker_cluster_resource_primitives ha_cluster_resource_primitives + +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Define parameter 'ha_cluster'" + when: __sap_ha_pacemaker_cluster_ha_cluster is defined + ansible.builtin.set_fact: + ha_cluster: "{{ __sap_ha_pacemaker_cluster_ha_cluster }}" + +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Define parameter 'ha_cluster_cluster_name'" + when: __sap_ha_pacemaker_cluster_cluster_name is defined + ansible.builtin.set_fact: + ha_cluster_cluster_name: "{{ __sap_ha_pacemaker_cluster_cluster_name }}" + +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Define parameter 'ha_cluster_cluster_properties'" + when: __sap_ha_pacemaker_cluster_cluster_properties is defined + ansible.builtin.set_fact: + ha_cluster_cluster_properties: "{{ __sap_ha_pacemaker_cluster_cluster_properties }}" + +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Define parameter 'ha_cluster_constraints_colocation'" + when: __sap_ha_pacemaker_cluster_constraints_colocation is defined + ansible.builtin.set_fact: + ha_cluster_constraints_colocation: "{{ __sap_ha_pacemaker_cluster_constraints_colocation }}" + +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Define parameter 'ha_cluster_constraints_location'" + when: __sap_ha_pacemaker_cluster_constraints_location is defined + ansible.builtin.set_fact: + ha_cluster_constraints_location: "{{ __sap_ha_pacemaker_cluster_constraints_location }}" + +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Define parameter 'ha_cluster_constraints_order'" + when: __sap_ha_pacemaker_cluster_constraints_order is defined + ansible.builtin.set_fact: + ha_cluster_constraints_order: "{{ __sap_ha_pacemaker_cluster_constraints_order }}" + +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Define parameter 'ha_cluster_extra_packages'" + when: __sap_ha_pacemaker_cluster_extra_packages is defined + ansible.builtin.set_fact: + ha_cluster_extra_packages: "{{ __sap_ha_pacemaker_cluster_extra_packages }}" + +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Define parameter 'ha_cluster_fence_agent_packages'" + when: __sap_ha_pacemaker_cluster_fence_agent_packages is defined + ansible.builtin.set_fact: + ha_cluster_fence_agent_packages: "{{ __sap_ha_pacemaker_cluster_fence_agent_packages }}" + +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Define parameter 'ha_cluster_hacluster_password'" + when: __sap_ha_pacemaker_cluster_hacluster_user_password is defined + ansible.builtin.set_fact: + ha_cluster_hacluster_password: "{{ __sap_ha_pacemaker_cluster_hacluster_user_password }}" + no_log: true # secure the credential + +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Define parameter 'ha_cluster_repos'" + when: __sap_ha_pacemaker_cluster_repos is defined + ansible.builtin.set_fact: + __ha_cluster_repos: "{{ __sap_ha_pacemaker_cluster_repos }}" + +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Define parameter 'ha_cluster_resource_clones'" + when: __sap_ha_pacemaker_cluster_resource_clones is defined + ansible.builtin.set_fact: + ha_cluster_resource_clones: "{{ __sap_ha_pacemaker_cluster_resource_clones }}" + +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Define parameter 'ha_cluster_resource_groups'" + when: __sap_ha_pacemaker_cluster_resource_groups is defined + ansible.builtin.set_fact: + ha_cluster_resource_groups: "{{ __sap_ha_pacemaker_cluster_resource_groups }}" + +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Define parameter 'ha_cluster_resource_primitives'" + when: __sap_ha_pacemaker_cluster_resource_primitives is defined + ansible.builtin.set_fact: + ha_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives }}" + no_log: true # be paranoid, there could be credentials in it diff --git a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_common.yml b/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_common.yml index 96a4bdb63..bc6e17140 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_common.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_common.yml @@ -1,29 +1,48 @@ --- -# Create or combine input parameters for the ha_cluster role. +# Combine input parameters with inherited vars from the 'ha_cluster' role. +# The inherited values take precedence. Some parameters are not required to be set. +# The 'ha_cluster' LSR will apply its role defaults. +# For mandatory parameters, sanity checks will be done separately. +# sap_ha_pacemaker_cluster_cluster_name -> user-defined or default inherited from {{ ha_cluster_cluster_name }} - name: "SAP HA Prepare Pacemaker - Set cluster name" + when: + - __sap_ha_pacemaker_cluster_cluster_name is not defined + - sap_ha_pacemaker_cluster_cluster_name is defined ansible.builtin.set_fact: - __sap_ha_pacemaker_cluster_cluster_name: "{{ ha_cluster_cluster_name | default(sap_ha_pacemaker_cluster_cluster_name) }}" + __sap_ha_pacemaker_cluster_cluster_name: "{{ sap_ha_pacemaker_cluster_cluster_name }}" +# sap_ha_pacemaker_cluster_hacluster_user_password -> user-defined or default inherited from {{ ha_cluster_hacluster_password }} - name: "SAP HA Prepare Pacemaker - Register the 'hacluster' user password" + when: + - __sap_ha_pacemaker_cluster_hacluster_user_password is not defined + - sap_ha_pacemaker_cluster_hacluster_user_password ansible.builtin.set_fact: - __sap_ha_pacemaker_cluster_hacluster_password: "{{ ha_cluster_hacluster_password | default(sap_ha_pacemaker_cluster_hacluster_password) }}" - no_log: true + __sap_ha_pacemaker_cluster_hacluster_user_password: "{{ sap_ha_pacemaker_cluster_hacluster_user_password }}" + no_log: true # secure the credential + + +# sap_ha_pacemaker_cluster_extra_packages -> user-defined, empty by global default +# __sap_ha_pacemaker_cluster_sap_extra_packages -> included from vars/* +# __sap_ha_pacemaker_cluster_platform_extra_packages -> included from vars/platform* - name: "SAP HA Prepare Pacemaker - Combine extra packages lists" ansible.builtin.set_fact: - __sap_ha_pacemaker_cluster_extra_packages: "{{ + __sap_ha_pacemaker_cluster_extra_packages: "{{ ( sap_ha_pacemaker_cluster_extra_packages - + - sap_ha_pacemaker_cluster_sap_extra_packages | default([]) - + - sap_ha_pacemaker_cluster_platform_extra_packages | default([]) - }}" + + __sap_ha_pacemaker_cluster_sap_extra_packages + + __sap_ha_pacemaker_cluster_platform_extra_packages + ) | unique | select() }}" + # remove duplicates and empty elements + +# sap_ha_pacemaker_cluster_fence_agent_minimal_packages -> global default +# sap_ha_pacemaker_cluster_fence_agent_packages -> global default +# __sap_ha_pacemaker_cluster_fence_agent_packages -> internal default (vars/main.yml) - name: "SAP HA Prepare Pacemaker - Combine fence agent packages lists" ansible.builtin.set_fact: - __sap_ha_pacemaker_cluster_fence_agent_packages: "{{ - sap_ha_pacemaker_cluster_fence_agent_packages - + - __sap_ha_pacemaker_cluster_fence_agent_packages - }}" + __sap_ha_pacemaker_cluster_fence_agent_packages: "{{ ( + sap_ha_pacemaker_cluster_fence_agent_minimal_packages + + sap_ha_pacemaker_cluster_fence_agent_packages + + __sap_ha_pacemaker_cluster_fence_agent_packages + ) | unique }}" diff --git a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_hana_common.yml b/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_hana_common.yml index 06def49c8..cfc6f757c 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_hana_common.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_hana_common.yml @@ -9,6 +9,15 @@ # TODO: add conditionals to verify that the same resource agent is not already # defined in user input variables. Conflicting user input should take precedence. +- name: "SAP HA Prepare Pacemaker - Define resource defaults for HANA clusters" + when: + - sap_ha_pacemaker_cluster_resource_defaults is not defined + or sap_ha_pacemaker_cluster_resource_defaults | length == 0 + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_resource_defaults: + resource-stickiness: 1000 + migration-threshold: 5000 + - name: "SAP HA Prepare Pacemaker - Add resource: SAP HANA Topology" ansible.builtin.set_fact: __sap_ha_pacemaker_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives + [__resource_hana_topology] }}" @@ -21,7 +30,7 @@ - name: SID value: "{{ sap_ha_pacemaker_cluster_hana_sid }}" - name: InstanceNumber - value: "{{ sap_ha_pacemaker_cluster_hana_instance_number }}" + value: "{{ sap_ha_pacemaker_cluster_hana_instance_nr }}" operations: - action: start attrs: @@ -52,7 +61,7 @@ - name: SID value: "{{ sap_ha_pacemaker_cluster_hana_sid }}" - name: InstanceNumber - value: "{{ sap_ha_pacemaker_cluster_hana_instance_number }}" + value: "{{ sap_ha_pacemaker_cluster_hana_instance_nr }}" - name: AUTOMATED_REGISTER value: "{{ sap_ha_pacemaker_cluster_hana_automated_register | string }}" - name: DUPLICATE_PRIMARY_TIMEOUT diff --git a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_netweaver_abap_ascs_ers.yml b/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_nwas_abap_ascs_ers.yml similarity index 53% rename from roles/sap_ha_pacemaker_cluster/tasks/construct_vars_netweaver_abap_ascs_ers.yml rename to roles/sap_ha_pacemaker_cluster/tasks/construct_vars_nwas_abap_ascs_ers.yml index 714ba306a..5d6b32cc9 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_netweaver_abap_ascs_ers.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_nwas_abap_ascs_ers.yml @@ -2,14 +2,65 @@ # Variables containing variables must be constructed with values # to be fed into the included ha_cluster role -# - put here all scale-up and scale-out common resources -# - certain differences like ra agent names are provided through -# type specific variables - # TODO: add conditionals to verify that the same resource agent is not already # defined in user input variables. Conflicting user input should take precedence. +# Several parameters are pre-defined from potentially inherited ha_cluster LSR definitions. +# They are necessary to be used for combining all cluster setup definitions. +# +# See tasks/ascertain_ha_cluster_in_inventory.yml: +# +# __sap_ha_pacemaker_cluster_cluster_properties: "{{ ha_cluster_cluster_properties }}" +# __sap_ha_pacemaker_cluster_constraints_colocation: "{{ ha_cluster_constraints_colocation }}" +# __sap_ha_pacemaker_cluster_constraints_location: "{{ ha_cluster_constraints_location }}" +# __sap_ha_pacemaker_cluster_constraints_order: "{{ ha_cluster_constraints_order }}" +# __sap_ha_pacemaker_cluster_fence_agent_packages: "{{ ha_cluster_fence_agent_packages }}" +# __sap_ha_pacemaker_cluster_repos: "{{ ha_cluster_repos }}" +# __sap_ha_pacemaker_cluster_resource_clones: "{{ ha_cluster_resource_clones }}" +# __sap_ha_pacemaker_cluster_resource_groups: "{{ ha_cluster_resource_groups }}" +# __sap_ha_pacemaker_cluster_resource_primitives: "{{ ha_cluster_resource_primitives }}" + + +### Different SAPInstance resource attributes for ENSA1 and ENSA2 +- name: "SAP HA Prepare Pacemaker - Define default ASCS/ERS instance attributes (ENSA2)" + when: not sap_ha_pacemaker_cluster_nwas_abap_ascs_ers_ensa1 + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_nwas_ascs_sapinstance_meta_attrs: + - name: resource-stickiness + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_resource_stickiness }}" + + __sap_ha_pacemaker_cluster_nwas_ers_sapinstance_instance_attrs: + - name: InstanceName + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_instance_name }}" + - name: START_PROFILE + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_start_profile_string }}" + - name: AUTOMATIC_RECOVER + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_automatic_recover_bool | string }}" + + +- name: "SAP HA Prepare Pacemaker - Define ASCS/ERS instance attributes (ENSA1)" + when: sap_ha_pacemaker_cluster_nwas_abap_ascs_ers_ensa1 + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_nwas_ascs_sapinstance_meta_attrs: + - name: resource-stickiness + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_resource_stickiness }}" + - name: migration-threshold + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_ensa1_migration_threshold }}" + - name: failure-timeout + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_ensa1_failure_timeout }}" + __sap_ha_pacemaker_cluster_nwas_ers_sapinstance_instance_attrs: + - name: InstanceName + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_instance_name }}" + - name: START_PROFILE + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_start_profile_string }}" + - name: AUTOMATIC_RECOVER + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_automatic_recover_bool | string }}" + - name: IS_ERS + value: true + + +### ASCS/ERS instance filesystems - name: "SAP HA Prepare Pacemaker - Add filesystem resources for ASCS/ERS to resource definition" ansible.builtin.set_fact: __sap_ha_pacemaker_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives + [__resource_filesystem] }}" @@ -17,9 +68,9 @@ __resource_filesystem: id: |- {%- if '/ASCS' in __mountpoint -%} - {% set idname = sap_ha_pacemaker_cluster_netweaver_abap_ascs_filesystem_resource_name %} + {% set idname = sap_ha_pacemaker_cluster_nwas_abap_ascs_filesystem_resource_name %} {%- elif '/ERS' in __mountpoint -%} - {% set idname = sap_ha_pacemaker_cluster_netweaver_abap_ers_filesystem_resource_name %} + {% set idname = sap_ha_pacemaker_cluster_nwas_abap_ers_filesystem_resource_name %} {%- endif -%} {{ idname }} agent: "ocf:heartbeat:Filesystem" @@ -100,7 +151,7 @@ {%- endfor %} __mountpoint: "{{ fsres_item }}" - loop: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ascs_ers_filesystems }}" + loop: "{{ __sap_ha_pacemaker_cluster_nwas_abap_ascs_ers_filesystems }}" loop_control: loop_var: fsres_item label: "{{ fsres_item }}" @@ -116,24 +167,18 @@ __sap_ha_pacemaker_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives + [__resource_sapinstance] }}" vars: __resource_sapinstance: - id: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ascs_sapinstance_resource_name }}" + id: "{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_resource_name }}" agent: "ocf:heartbeat:SAPInstance" instance_attrs: - attrs: - name: InstanceName - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ascs_sapinstance_instance_name }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_instance_name }}" - name: START_PROFILE - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ascs_sapinstance_start_profile_string }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_start_profile_string }}" - name: AUTOMATIC_RECOVER - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ascs_sapinstance_automatic_recover_bool | string }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_automatic_recover_bool | string }}" meta_attrs: - - attrs: - - name: resource-stickiness - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ascs_sapinstance_resource_stickiness }}" - - name: migration-threshold - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ascs_sapinstance_migration_threshold }}" - - name: failure-timeout - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ascs_sapinstance_failure_timeout }}" + - attrs: "{{ __sap_ha_pacemaker_cluster_nwas_ascs_sapinstance_meta_attrs }}" operations: - action: start attrs: @@ -158,22 +203,6 @@ when: - __resource_sapinstance.id not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) -# Order Constraint: ASCS filesystem should start before instance -- name: "SAP HA Prepare Pacemaker - Add order constraint: first start ASCS filesystem, then ASCS instance" - ansible.builtin.set_fact: - __sap_ha_pacemaker_cluster_constraints_order: "{{ __sap_ha_pacemaker_cluster_constraints_order + [__constraint_order_ascs_fs] }}" - vars: - __constraint_order_ascs_fs: - resource_first: - id: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ascs_filesystem_resource_name }}" - role: started - resource_then: - id: "{{ sap_ha_pacemaker_cluster_netweaver_sid }}_ASCS{{ sap_ha_pacemaker_cluster_netweaver_instance_number }}_group" - options: - - name: symmetrical - value: "false" - when: - - __constraint_order_ascs_fs.resource_first not in (__sap_ha_pacemaker_cluster_constraints_order | map(attribute='resource_first')) # ERS instance resource definition - name: "SAP HA Prepare Pacemaker - Add resource: SAPInstance for Enqueue Replication Service (ABAP ERS)" @@ -181,26 +210,10 @@ __sap_ha_pacemaker_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives + [__resource_sapinstance_ers] }}" vars: __resource_sapinstance_ers: - id: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ers_sapinstance_resource_name }}" + id: "{{ sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_resource_name }}" agent: "ocf:heartbeat:SAPInstance" instance_attrs: - - attrs: - - name: InstanceName - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ers_sapinstance_instance_name }}" - - name: START_PROFILE - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ers_sapinstance_start_profile_string }}" - - name: AUTOMATIC_RECOVER - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ers_sapinstance_automatic_recover_bool | string }}" - - name: IS_ERS - value: "true" - meta_attrs: - - attrs: - - name: resource-stickiness - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ers_sapinstance_resource_stickiness }}" - - name: migration-threshold - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ers_sapinstance_migration_threshold }}" - - name: failure-timeout - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ers_sapinstance_failure_timeout }}" + - attrs: "{{ __sap_ha_pacemaker_cluster_nwas_ers_sapinstance_instance_attrs }}" operations: - action: start attrs: @@ -225,22 +238,6 @@ when: - __resource_sapinstance_ers.id not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) -# Order Constraint: ERS filesystem should start before instance -- name: "SAP HA Prepare Pacemaker - Add order constraint: first start ERS filesystem, then ERS instance" - ansible.builtin.set_fact: - __sap_ha_pacemaker_cluster_constraints_order: "{{ __sap_ha_pacemaker_cluster_constraints_order + [__constraint_order_ers_fs] }}" - vars: - __constraint_order_ers_fs: - resource_first: - id: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ers_filesystem_resource_name }}" - role: started - resource_then: - id: "{{ sap_ha_pacemaker_cluster_netweaver_sid }}_ERS{{ sap_ha_pacemaker_cluster_netweaver_instance_number }}_group" - options: - - name: symmetrical - value: "false" - when: - - __constraint_order_ers_fs.resource_first not in (__sap_ha_pacemaker_cluster_constraints_order | map(attribute='resource_first')) ################################################# # Group resources that belong together @@ -250,20 +247,23 @@ # - ASCS filesystem # - ASCS instance # - ASCS VIP +# The order of the resources in the group define the order in which they are +# started - resources are stopped in reverse order. + - name: "SAP HA Prepare Pacemaker - Add resource group for ASCS resources" ansible.builtin.set_fact: __sap_ha_pacemaker_cluster_resource_groups: "{{ __sap_ha_pacemaker_cluster_resource_groups + [__ascs_group] }}" vars: __ascs_group: - id: "{{ sap_ha_pacemaker_cluster_netweaver_sid }}_ASCS{{ sap_ha_pacemaker_cluster_netweaver_instance_number }}_group" + id: "{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_ASCS{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_instance_nr }}_group" resource_ids: - - "{{ sap_ha_pacemaker_cluster_netweaver_abap_ascs_filesystem_resource_name }}" - - "{{ sap_ha_pacemaker_cluster_netweaver_abap_ascs_sapinstance_resource_name }}" - - "{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ sap_ha_pacemaker_cluster_vip_address | select('search', 'ascs') | join('') }}" + - "{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_filesystem_resource_name }}" + - "{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_resource_name }}" + - "{{ sap_ha_pacemaker_cluster_vip_nwas_abap_ascs_resource_name }}" meta_attrs: - attrs: - name: resource-stickiness - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ers_sapinstance_resource_stickiness }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_group_stickiness }}" when: - __ascs_group.id is not in (__sap_ha_pacemaker_cluster_resource_groups | map(attribute='id')) @@ -271,35 +271,46 @@ # - ERS filesystem # - ERS instance # - ERS VIP +# The order of the resources in the group define the order in which they are +# started - resources are stopped in reverse order. + - name: "SAP HA Prepare Pacemaker - Add resource group for ERS resources" ansible.builtin.set_fact: __sap_ha_pacemaker_cluster_resource_groups: "{{ __sap_ha_pacemaker_cluster_resource_groups + [__ers_group] }}" vars: __ers_group: - id: "{{ sap_ha_pacemaker_cluster_netweaver_sid }}_ERS{{ sap_ha_pacemaker_cluster_netweaver_instance_number }}_group" + id: "{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_ERS{{ sap_ha_pacemaker_cluster_nwas_abap_ers_instance_nr }}_group" resource_ids: - - "{{ sap_ha_pacemaker_cluster_netweaver_abap_ers_filesystem_resource_name }}" - - "{{ sap_ha_pacemaker_cluster_netweaver_abap_ers_sapinstance_resource_name }}" - - "{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ sap_ha_pacemaker_cluster_vip_address | select('search', 'ers') | join('') }}" + - "{{ sap_ha_pacemaker_cluster_nwas_abap_ers_filesystem_resource_name }}" + - "{{ sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_resource_name }}" + - "{{ sap_ha_pacemaker_cluster_vip_nwas_abap_ers_resource_name }}" when: - __ers_group.id is not in (__sap_ha_pacemaker_cluster_resource_groups | map(attribute='id')) ################################################# -# Constraints between the groups +# Constraints ################################################# +# Constraint parameters are pre-defined from potentially inherited ha_cluster LSR definitions. +# Constraint definitions are combined into these parameters. +# See tasks/ascertain_ha_cluster_in_inventory.yml: +# +# __sap_ha_pacemaker_cluster_constraints_colocation: "{{ ha_cluster_constraints_colocation }}" +# __sap_ha_pacemaker_cluster_constraints_location: "{{ ha_cluster_constraints_location }}" +# __sap_ha_pacemaker_cluster_constraints_order: "{{ ha_cluster_constraints_order }}" + # ERS and ASCS resource groups should try to avoid running on the same node -- name: "SAP HA Prepare Pacemaker - Add colocation constraint: NetWeaver ERS and ASCS avoid on the same node" +- name: "SAP HA Prepare Pacemaker - Add colocation constraint: ERS avoids to run on the ASCS node" ansible.builtin.set_fact: __sap_ha_pacemaker_cluster_constraints_colocation: "{{ __sap_ha_pacemaker_cluster_constraints_colocation + [__constraint_colo_ers] }}" vars: __constraint_colo_ers: resource_leader: - id: "{{ sap_ha_pacemaker_cluster_netweaver_sid }}_ASCS{{ sap_ha_pacemaker_cluster_netweaver_instance_number }}_group" + id: "{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_ASCS{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_instance_nr }}_group" role: started resource_follower: - id: "{{ sap_ha_pacemaker_cluster_netweaver_sid }}_ERS{{ sap_ha_pacemaker_cluster_netweaver_instance_number }}_group" + id: "{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_ERS{{ sap_ha_pacemaker_cluster_nwas_abap_ers_instance_nr }}_group" options: - name: score value: -5000 @@ -313,14 +324,58 @@ vars: __constraint_order_ascs_ers: resource_first: - id: "{{ sap_ha_pacemaker_cluster_netweaver_sid }}_ASCS{{ sap_ha_pacemaker_cluster_netweaver_instance_number }}_group" + id: "{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_ASCS{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_instance_nr }}_group" role: started resource_then: - id: "{{ sap_ha_pacemaker_cluster_netweaver_sid }}_ERS{{ sap_ha_pacemaker_cluster_netweaver_instance_number }}_group" + id: "{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_ERS{{ sap_ha_pacemaker_cluster_nwas_abap_ers_instance_nr }}_group" options: - name: symmetrical value: "false" - name: kind value: Optional +# when: +# - __constraint_order_ascs_ers.resource_then not in (__sap_ha_pacemaker_cluster_constraints_order | map(attribute='resource_then')) + +# ENSA1 only: location rule for ASCS to follow ERS +- name: "SAP HA Prepare Pacemaker - Add location constraint: ASCS follows ERS in ENSA1 setup" + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_constraints_location: "{{ __sap_ha_pacemaker_cluster_constraints_location + [__constraint_location_ascs_ers] }}" + vars: + __constraint_location_ascs_ers: + resource: + id: "{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_resource_name }}" + rule: "runs_ers_{{ sap_ha_pacemaker_cluster_nwas_abap_sid }} eq 1" + options: + - name: score + value: 2000 + when: + - sap_ha_pacemaker_cluster_nwas_abap_ascs_ers_ensa1 + + +# When /sapmnt is managed by the cluster, +# start instance groups only after the SAPMNT resource is running. +- name: "SAP HA Prepare Pacemaker - Add order constraint: first start /sapmnt, then start ASCS group" + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_constraints_order: "{{ __sap_ha_pacemaker_cluster_constraints_order + [__constraint_order_sapmnt] }}" + vars: + __constraint_order_sapmnt: + resource_first: + id: "{{ sap_ha_pacemaker_cluster_nwas_sapmnt_filesystem_resource_name }}-clone" + role: started + resource_then: + id: "{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_ASCS{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_instance_nr }}_group" + when: + - sap_ha_pacemaker_cluster_nwas_shared_filesystems_cluster_managed + +- name: "SAP HA Prepare Pacemaker - Add order constraint: first start /sapmnt, then start ERS group" + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_constraints_order: "{{ __sap_ha_pacemaker_cluster_constraints_order + [__constraint_order_sapmnt] }}" + vars: + __constraint_order_sapmnt: + resource_first: + id: "{{ sap_ha_pacemaker_cluster_nwas_sapmnt_filesystem_resource_name }}-clone" + role: started + resource_then: + id: "{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}_ERS{{ sap_ha_pacemaker_cluster_nwas_abap_ers_instance_nr }}_group" when: - - __constraint_order_ascs_ers.resource_then not in (__sap_ha_pacemaker_cluster_constraints_order | map(attribute='resource_then')) + - sap_ha_pacemaker_cluster_nwas_shared_filesystems_cluster_managed diff --git a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_netweaver_abap_pas_aas.yml b/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_nwas_abap_pas_aas.yml similarity index 66% rename from roles/sap_ha_pacemaker_cluster/tasks/construct_vars_netweaver_abap_pas_aas.yml rename to roles/sap_ha_pacemaker_cluster/tasks/construct_vars_nwas_abap_pas_aas.yml index 54b2d7834..17be8c306 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_netweaver_abap_pas_aas.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_nwas_abap_pas_aas.yml @@ -15,20 +15,20 @@ __sap_ha_pacemaker_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives + [__resource_filesystem] }}" vars: __resource_filesystem: - id: "{{ sap_ha_pacemaker_cluster_netweaver_abap_pas_filesystem_resource_name }}" + id: "{{ sap_ha_pacemaker_cluster_nwas_abap_pas_filesystem_resource_name }}" agent: "ocf:heartbeat:Filesystem" instance_attrs: - attrs: - name: device - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_pas_filesystem_host_mount_path }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_pas_filesystem_host_mount_path }}" - name: directory - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_pas_filesystem_local_mount_path }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_pas_filesystem_local_mount_path }}" - name: fstype - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_pas_filesystem_fstype }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_pas_filesystem_fstype }}" - name: options - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_pas_filesystem_options_string }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_pas_filesystem_options_string }}" - name: force_unmount - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_pas_filesystem_force_unmount }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_pas_filesystem_force_unmount }}" operations: - action: start attrs: @@ -56,20 +56,20 @@ __sap_ha_pacemaker_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives + [__resource_filesystem] }}" vars: __resource_filesystem: - id: "{{ sap_ha_pacemaker_cluster_netweaver_abap_aas_filesystem_resource_name }}" + id: "{{ sap_ha_pacemaker_cluster_nwas_abap_aas_filesystem_resource_name }}" agent: "ocf:heartbeat:Filesystem" instance_attrs: - attrs: - name: device - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_aas_filesystem_host_mount_path }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_aas_filesystem_host_mount_path }}" - name: directory - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_aas_filesystem_local_mount_path }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_aas_filesystem_local_mount_path }}" - name: fstype - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_aas_filesystem_fstype }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_aas_filesystem_fstype }}" - name: options - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_aas_filesystem_options_string }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_aas_filesystem_options_string }}" - name: force_unmount - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_aas_filesystem_force_unmount }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_aas_filesystem_force_unmount }}" operations: - action: start attrs: @@ -97,24 +97,24 @@ __sap_ha_pacemaker_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives + [__resource_sapinstance] }}" vars: __resource_sapinstance: - id: "{{ sap_ha_pacemaker_cluster_netweaver_abap_pas_sapinstance_resource_name }}" + id: "{{ sap_ha_pacemaker_cluster_nwas_abap_pas_sapinstance_resource_name }}" agent: "ocf:heartbeat:SAPInstance" instance_attrs: - attrs: - name: InstanceName - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_pas_sapinstance_instance_name }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_pas_sapinstance_instance_name }}" - name: START_PROFILE - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_pas_sapinstance_start_profile_string }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_pas_sapinstance_start_profile_string }}" - name: AUTOMATIC_RECOVER - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_pas_sapinstance_automatic_recover_bool | string }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_pas_sapinstance_automatic_recover_bool | string }}" meta_attrs: - attrs: - name: resource-stickiness - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_pas_sapinstance_resource_stickiness }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_pas_sapinstance_resource_stickiness }}" - name: migration-threshold - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_pas_sapinstance_migration_threshold }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_pas_sapinstance_migration_threshold }}" - name: failure-timeout - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_pas_sapinstance_failure_timeout }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_pas_sapinstance_failure_timeout }}" operations: - action: start attrs: @@ -144,24 +144,24 @@ __sap_ha_pacemaker_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives + [__resource_sapinstance_ers] }}" vars: __resource_sapinstance_ers: - id: "{{ sap_ha_pacemaker_cluster_netweaver_abap_aas_sapinstance_resource_name }}" + id: "{{ sap_ha_pacemaker_cluster_nwas_abap_aas_sapinstance_resource_name }}" agent: "ocf:heartbeat:SAPInstance" instance_attrs: - attrs: - name: InstanceName - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_aas_sapinstance_instance_name }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_aas_sapinstance_instance_name }}" - name: START_PROFILE - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_aas_sapinstance_start_profile_string }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_aas_sapinstance_start_profile_string }}" - name: AUTOMATIC_RECOVER - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_aas_sapinstance_automatic_recover_bool | string }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_aas_sapinstance_automatic_recover_bool | string }}" meta_attrs: - attrs: - name: resource-stickiness - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_aas_sapinstance_resource_stickiness }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_aas_sapinstance_resource_stickiness }}" - name: migration-threshold - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_aas_sapinstance_migration_threshold }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_aas_sapinstance_migration_threshold }}" - name: failure-timeout - value: "{{ sap_ha_pacemaker_cluster_netweaver_abap_aas_sapinstance_failure_timeout }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_abap_aas_sapinstance_failure_timeout }}" operations: - action: start attrs: diff --git a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_netweaver_common.yml b/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_nwas_common.yml similarity index 76% rename from roles/sap_ha_pacemaker_cluster/tasks/construct_vars_netweaver_common.yml rename to roles/sap_ha_pacemaker_cluster/tasks/construct_vars_nwas_common.yml index b1d41f4fb..ccaae9c04 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_netweaver_common.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_nwas_common.yml @@ -3,12 +3,19 @@ # to be fed into the included ha_cluster role # - put here all NetWeaver common resources -# - certain differences like ra agent names are provided through -# type specific variables # TODO: add conditionals to verify that the same resource agent is not already # defined in user input variables. Conflicting user input should take precedence. +- name: "SAP HA Prepare Pacemaker - Define resource defaults for NetWeaver clusters" + when: + - sap_ha_pacemaker_cluster_resource_defaults is not defined + or sap_ha_pacemaker_cluster_resource_defaults | length == 0 + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_resource_defaults: + resource-stickiness: 1 + migration-threshold: 3 + - name: "SAP HA Prepare Pacemaker - Add NetWeaver common filesystem resources to resource definition" ansible.builtin.set_fact: @@ -17,11 +24,11 @@ __resource_filesystem: id: |- {%- if '/sapmnt' in __mountpoint -%} - {% set idname = sap_ha_pacemaker_cluster_netweaver_sapmnt_filesystem_resource_name %} + {% set idname = sap_ha_pacemaker_cluster_nwas_sapmnt_filesystem_resource_name %} {% elif '/usr/sap/trans' in __mountpoint -%} - {% set idname = sap_ha_pacemaker_cluster_netweaver_transports_filesystem_resource_name %} - {% elif '/usr/sap/' + sap_ha_pacemaker_cluster_netweaver_sid + '/SYS' in __mountpoint -%} - {% set idname = sap_ha_pacemaker_cluster_netweaver_sys_filesystem_resource_name %} + {% set idname = sap_ha_pacemaker_cluster_nwas_transports_filesystem_resource_name %} + {% elif '/usr/sap/' + sap_ha_pacemaker_cluster_nwas_abap_sid + '/SYS' in __mountpoint -%} + {% set idname = sap_ha_pacemaker_cluster_nwas_sys_filesystem_resource_name %} {% endif %} {{ idname }} @@ -64,13 +71,13 @@ __nfs_server: "{{ commonfs_item.nfs_server | default(sap_ha_pacemaker_cluster_storage_nfs_server) | regex_replace('/$', '') }}" __nfs_path: |- {%- if '/usr/sap' in commonfs_item.nfs_path and '/usr/sap/trans' not in commonfs_item.nfs_path -%} - {{ commonfs_item.nfs_path | regex_replace('^/', '') | regex_replace('/$', '') }}/{{ sap_ha_pacemaker_cluster_netweaver_sid }}/SYS + {{ commonfs_item.nfs_path | regex_replace('^/', '') | regex_replace('/$', '') }}/{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}/SYS {%- else -%} {{ commonfs_item.nfs_path | regex_replace('^/', '') | regex_replace('/$', '') }} {%- endif %} __mountpoint: |- {%- if commonfs_item.mountpoint | regex_replace('/$', '') == '/usr/sap' -%} - {{ commonfs_item.mountpoint | regex_replace('/$', '') }}/{{ sap_ha_pacemaker_cluster_netweaver_sid }}/SYS + {{ commonfs_item.mountpoint | regex_replace('/$', '') }}/{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}/SYS {%- else -%} {{ commonfs_item.mountpoint | regex_replace('/$', '') }} {%- endif %} @@ -80,12 +87,15 @@ loop_var: commonfs_item label: "{{ commonfs_item.name }}" when: + - sap_ha_pacemaker_cluster_nwas_shared_filesystems_cluster_managed - commonfs_item.mountpoint is defined - commonfs_item.nfs_path is defined - "'/usr/sap' in commonfs_item.mountpoint or '/sapmnt' in commonfs_item.mountpoint" - __resource_filesystem.id not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) +# End of shared filesystems resource definition task + # The shared/common filesystems are clones. - name: "SAP HA Prepare Pacemaker - Add resource clones for NetWeaver common shared filesystems" @@ -95,11 +105,11 @@ __clone_common_filesystem: resource_id: |- {%- if '/sapmnt' in __mountpoint -%} - {% set idname = sap_ha_pacemaker_cluster_netweaver_sapmnt_filesystem_resource_name %} + {% set idname = sap_ha_pacemaker_cluster_nwas_sapmnt_filesystem_resource_name %} {% elif '/usr/sap/trans' in __mountpoint -%} - {% set idname = sap_ha_pacemaker_cluster_netweaver_transports_filesystem_resource_name %} - {% elif '/usr/sap/' + sap_ha_pacemaker_cluster_netweaver_sid + '/SYS' in __mountpoint -%} - {% set idname = sap_ha_pacemaker_cluster_netweaver_sys_filesystem_resource_name %} + {% set idname = sap_ha_pacemaker_cluster_nwas_transports_filesystem_resource_name %} + {% elif '/usr/sap/' + sap_ha_pacemaker_cluster_nwas_abap_sid + '/SYS' in __mountpoint -%} + {% set idname = sap_ha_pacemaker_cluster_nwas_sys_filesystem_resource_name %} {% endif %} {{ idname }} meta_attrs: @@ -109,7 +119,7 @@ __mountpoint: |- {%- if commonfsclone_item.mountpoint | regex_replace('/$', '') == '/usr/sap' -%} - {{ commonfsclone_item.mountpoint | regex_replace('/$', '') }}/{{ sap_ha_pacemaker_cluster_netweaver_sid }}/SYS + {{ commonfsclone_item.mountpoint | regex_replace('/$', '') }}/{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}/SYS {%- else -%} {{ commonfsclone_item.mountpoint | regex_replace('/$', '') }} {%- endif %} @@ -119,6 +129,7 @@ loop_var: commonfsclone_item label: "{{ commonfsclone_item.name }}" when: + - sap_ha_pacemaker_cluster_nwas_shared_filesystems_cluster_managed - commonfsclone_item.mountpoint is defined - commonfsclone_item.nfs_path is defined - "'/usr/sap' in commonfsclone_item.mountpoint diff --git a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_netweaver_java_scs_ers.yml b/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_nwas_java_scs_ers.yml similarity index 72% rename from roles/sap_ha_pacemaker_cluster/tasks/construct_vars_netweaver_java_scs_ers.yml rename to roles/sap_ha_pacemaker_cluster/tasks/construct_vars_nwas_java_scs_ers.yml index 67e66aabb..42867c02c 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_netweaver_java_scs_ers.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_nwas_java_scs_ers.yml @@ -15,20 +15,20 @@ __sap_ha_pacemaker_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives + [__resource_filesystem] }}" vars: __resource_filesystem: - id: "{{ sap_ha_pacemaker_cluster_netweaver_java_scs_filesystem_resource_name }}" + id: "{{ sap_ha_pacemaker_cluster_nwas_java_scs_filesystem_resource_name }}" agent: "ocf:heartbeat:Filesystem" instance_attrs: - attrs: - name: device - value: "{{ sap_ha_pacemaker_cluster_netweaver_java_scs_filesystem_host_mount_path }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_java_scs_filesystem_host_mount_path }}" - name: directory - value: "{{ sap_ha_pacemaker_cluster_netweaver_java_scs_filesystem_local_mount_path }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_java_scs_filesystem_local_mount_path }}" - name: fstype - value: "{{ sap_ha_pacemaker_cluster_netweaver_java_scs_filesystem_fstype }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_java_scs_filesystem_fstype }}" - name: options - value: "{{ sap_ha_pacemaker_cluster_netweaver_java_scs_filesystem_options_string }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_java_scs_filesystem_options_string }}" - name: force_unmount - value: "{{ sap_ha_pacemaker_cluster_netweaver_java_scs_filesystem_force_unmount }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_java_scs_filesystem_force_unmount }}" operations: - action: start attrs: @@ -56,20 +56,20 @@ __sap_ha_pacemaker_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives + [__resource_filesystem] }}" vars: __resource_filesystem: - id: "{{ sap_ha_pacemaker_cluster_netweaver_java_ers_filesystem_resource_name }}" + id: "{{ sap_ha_pacemaker_cluster_nwas_java_ers_filesystem_resource_name }}" agent: "ocf:heartbeat:Filesystem" instance_attrs: - attrs: - name: device - value: "{{ sap_ha_pacemaker_cluster_netweaver_java_ers_filesystem_host_mount_path }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_java_ers_filesystem_host_mount_path }}" - name: directory - value: "{{ sap_ha_pacemaker_cluster_netweaver_java_ers_filesystem_local_mount_path }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_java_ers_filesystem_local_mount_path }}" - name: fstype - value: "{{ sap_ha_pacemaker_cluster_netweaver_java_ers_filesystem_fstype }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_java_ers_filesystem_fstype }}" - name: options - value: "{{ sap_ha_pacemaker_cluster_netweaver_java_ers_filesystem_options_string }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_java_ers_filesystem_options_string }}" - name: force_unmount - value: "{{ sap_ha_pacemaker_cluster_netweaver_java_ers_filesystem_force_unmount }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_java_ers_filesystem_force_unmount }}" operations: - action: start attrs: @@ -98,24 +98,24 @@ __sap_ha_pacemaker_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives + [__resource_sapinstance] }}" vars: __resource_sapinstance: - id: "{{ sap_ha_pacemaker_cluster_netweaver_java_scs_sapinstance_resource_name }}" + id: "{{ sap_ha_pacemaker_cluster_nwas_java_scs_sapinstance_resource_name }}" agent: "ocf:heartbeat:SAPInstance" instance_attrs: - attrs: - name: InstanceName - value: "{{ sap_ha_pacemaker_cluster_netweaver_java_scs_sapinstance_instance_name }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_java_scs_sapinstance_instance_name }}" - name: START_PROFILE - value: "{{ sap_ha_pacemaker_cluster_netweaver_java_scs_sapinstance_start_profile_string }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_java_scs_sapinstance_start_profile_string }}" - name: AUTOMATIC_RECOVER - value: "{{ sap_ha_pacemaker_cluster_netweaver_java_scs_sapinstance_automatic_recover_bool | string }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_java_scs_sapinstance_automatic_recover_bool | string }}" meta_attrs: - attrs: - name: resource-stickiness - value: "{{ sap_ha_pacemaker_cluster_netweaver_java_scs_sapinstance_resource_stickiness }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_java_scs_sapinstance_resource_stickiness }}" - name: migration-threshold - value: "{{ sap_ha_pacemaker_cluster_netweaver_java_scs_sapinstance_migration_threshold }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_java_scs_sapinstance_migration_threshold }}" - name: failure-timeout - value: "{{ sap_ha_pacemaker_cluster_netweaver_java_scs_sapinstance_failure_timeout }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_java_scs_sapinstance_failure_timeout }}" operations: - action: start attrs: @@ -145,24 +145,24 @@ __sap_ha_pacemaker_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives + [__resource_sapinstance_ers] }}" vars: __resource_sapinstance_ers: - id: "{{ sap_ha_pacemaker_cluster_netweaver_java_ers_sapinstance_resource_name }}" + id: "{{ sap_ha_pacemaker_cluster_nwas_java_ers_sapinstance_resource_name }}" agent: "ocf:heartbeat:SAPInstance" instance_attrs: - attrs: - name: InstanceName - value: "{{ sap_ha_pacemaker_cluster_netweaver_java_ers_sapinstance_instance_name }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_java_ers_sapinstance_instance_name }}" - name: START_PROFILE - value: "{{ sap_ha_pacemaker_cluster_netweaver_java_ers_sapinstance_start_profile_string }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_java_ers_sapinstance_start_profile_string }}" - name: AUTOMATIC_RECOVER - value: "{{ sap_ha_pacemaker_cluster_netweaver_java_ers_sapinstance_automatic_recover_bool | string }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_java_ers_sapinstance_automatic_recover_bool | string }}" meta_attrs: - attrs: - name: resource-stickiness - value: "{{ sap_ha_pacemaker_cluster_netweaver_java_ers_sapinstance_resource_stickiness }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_java_ers_sapinstance_resource_stickiness }}" - name: migration-threshold - value: "{{ sap_ha_pacemaker_cluster_netweaver_java_ers_sapinstance_migration_threshold }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_java_ers_sapinstance_migration_threshold }}" - name: failure-timeout - value: "{{ sap_ha_pacemaker_cluster_netweaver_java_ers_sapinstance_failure_timeout }}" + value: "{{ sap_ha_pacemaker_cluster_nwas_java_ers_sapinstance_failure_timeout }}" operations: - action: start attrs: @@ -193,7 +193,7 @@ __sap_ha_pacemaker_cluster_resource_clones: "{{ __sap_ha_pacemaker_cluster_resource_clones + [__clone_filesystem] }}" vars: __clone_filesystem: - resource_id: "{{ sap_ha_pacemaker_cluster_netweaver_java_scs_filesystem_resource_name }}" + resource_id: "{{ sap_ha_pacemaker_cluster_nwas_java_scs_filesystem_resource_name }}" promotable: "no" meta_attrs: - attrs: @@ -211,7 +211,7 @@ __sap_ha_pacemaker_cluster_resource_clones: "{{ __sap_ha_pacemaker_cluster_resource_clones + [__clone_filesystem] }}" vars: __clone_filesystem: - resource_id: "{{ sap_ha_pacemaker_cluster_netweaver_java_ers_filesystem_resource_name }}" + resource_id: "{{ sap_ha_pacemaker_cluster_nwas_java_ers_filesystem_resource_name }}" promotable: "no" meta_attrs: - attrs: @@ -230,7 +230,7 @@ __sap_ha_pacemaker_cluster_resource_clones: "{{ __sap_ha_pacemaker_cluster_resource_clones + [__clone_sapinstance] }}" vars: __clone_sapinstance: - resource_id: "{{ sap_ha_pacemaker_cluster_netweaver_java_scs_sapinstance_resource_name }}" + resource_id: "{{ sap_ha_pacemaker_cluster_nwas_java_scs_sapinstance_resource_name }}" promotable: "yes" meta_attrs: - attrs: @@ -248,7 +248,7 @@ __sap_ha_pacemaker_cluster_resource_clones: "{{ __sap_ha_pacemaker_cluster_resource_clones + [__clone_sapinstance_ers] }}" vars: __clone_sapinstance_ers: - resource_id: "{{ sap_ha_pacemaker_cluster_netweaver_java_ers_sapinstance_resource_name }}" + resource_id: "{{ sap_ha_pacemaker_cluster_nwas_java_ers_sapinstance_resource_name }}" promotable: "yes" meta_attrs: - attrs: @@ -268,10 +268,10 @@ vars: __constraint_order_sapinstance: resource_first: - id: "{{ sap_ha_pacemaker_cluster_netweaver_java_scs_sapinstance_resource_clone_name }}" + id: "{{ sap_ha_pacemaker_cluster_nwas_java_scs_sapinstance_resource_clone_name }}" action: start resource_then: - id: "{{ sap_ha_pacemaker_cluster_netweaver_java_ers_sapinstance_resource_clone_name }}" + id: "{{ sap_ha_pacemaker_cluster_nwas_java_ers_sapinstance_resource_clone_name }}" action: start options: - name: symmetrical diff --git a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_stonith.yml b/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_stonith.yml index 0c87c43bf..43da8bf1b 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_stonith.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_stonith.yml @@ -2,20 +2,42 @@ # The following variables are constructed here in order to be provided as # input for the included 'ha_cluster' system role. -- name: "SAP HA Prepare Pacemaker - Block when no STONITH resource is defined" +### Block for disabling stonith when no stonith resource definition is found +# +# This block is entered when +# - no default stonith resource is defined and no custom is defined either +# - an empty custom is defined to override any default (defined or not) +- name: "SAP HA Prepare Pacemaker - (STONITH) Block when no STONITH resource is defined" when: - - sap_ha_pacemaker_cluster_stonith_default is not defined - or sap_ha_pacemaker_cluster_stonith_default | length == 0 - - sap_ha_pacemaker_cluster_stonith_custom is not defined - or sap_ha_pacemaker_cluster_stonith_custom | length == 0 + - ( + sap_ha_pacemaker_cluster_stonith_custom is defined + and + ( + sap_ha_pacemaker_cluster_stonith_custom == '' + or sap_ha_pacemaker_cluster_stonith_custom | length == 0 + ) + ) + or + ( + sap_ha_pacemaker_cluster_stonith_custom is not defined + and sap_ha_pacemaker_cluster_stonith_default is defined + and + ( + sap_ha_pacemaker_cluster_stonith_default == '' + or sap_ha_pacemaker_cluster_stonith_default | length == 0 + ) + ) + or + ( + sap_ha_pacemaker_cluster_stonith_custom is not defined + and sap_ha_pacemaker_cluster_stonith_default is not defined + ) block: - - name: "SAP HA Prepare Pacemaker - Set STONITH to disabled when no fencing resource is defined" + - name: "SAP HA Prepare Pacemaker - (STONITH) Set to disabled when no fencing resource is defined" ansible.builtin.set_fact: - __sap_ha_pacemaker_cluster_cluster_properties: - - attrs: - - name: stonith-enabled - value: false + sap_ha_pacemaker_cluster_cluster_properties: + "{{ sap_ha_pacemaker_cluster_cluster_properties | combine({ 'stonith-enabled': false }) }}" - name: "SAP HA Prepare Pacemaker - Warn that there is no STONITH configured" ansible.builtin.pause: @@ -27,15 +49,19 @@ Recommendation: Add a STONITH resource and set cluster property "stonith-enabled=true" before using this cluster for production services. -# END of block -- name: "SAP HA Prepare Pacemaker - Define cluster stonith properties" +# END of block for disabling stonith + + +- name: "SAP HA Prepare Pacemaker - (STONITH) Define cluster properties" when: - sap_ha_pacemaker_cluster_cluster_properties is defined - sap_ha_pacemaker_cluster_cluster_properties is iterable - sap_ha_pacemaker_cluster_cluster_properties | length > 0 ansible.builtin.set_fact: - __sap_ha_pacemaker_cluster_cluster_properties: + __sap_ha_pacemaker_cluster_cluster_properties: "{{ __sap_ha_pacemaker_cluster_cluster_properties | default([]) + __stonith_properties }}" + vars: + __stonith_properties: - attrs: |- {% set attrs = __sap_ha_pacemaker_cluster_cluster_properties | map(attribute='attrs') | flatten -%} {%- for default_cluster_properties in (sap_ha_pacemaker_cluster_cluster_properties | dict2items) -%} @@ -59,7 +85,7 @@ # - generic pacemaker fence resource options # (see defaults: sap_ha_pacemaker_cluster_fence_options) -- name: "SAP HA Prepare Pacemaker - Assemble the stonith resource definition from platform default" +- name: "SAP HA Prepare Pacemaker - (STONITH) Assemble the resource definition from platform default" when: - sap_ha_pacemaker_cluster_stonith_default is defined - sap_ha_pacemaker_cluster_stonith_custom is not defined @@ -93,7 +119,7 @@ {%- endfor %} {{ attrs }} -- name: "SAP HA Prepare Pacemaker - Assemble the stonith resources from custom definition" +- name: "SAP HA Prepare Pacemaker - (STONITH) Assemble the resources from custom definition" when: - sap_ha_pacemaker_cluster_stonith_custom is defined ansible.builtin.set_fact: @@ -120,7 +146,7 @@ # The STONITH resource is an element in the cluster_resource_primitives list -- name: "SAP HA Prepare Pacemaker - Construct stonith resources definition" +- name: "SAP HA Prepare Pacemaker - (STONITH) Construct resources definition" when: - __sap_ha_pacemaker_cluster_stonith_resource is defined ansible.builtin.set_fact: diff --git a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_vip_constraints_hana.yml b/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_vip_constraints_hana.yml index e632bbaec..8049ef7ec 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_vip_constraints_hana.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_vip_constraints_hana.yml @@ -2,7 +2,7 @@ # Reminder: This file is included in a loop over a dictionary. # Start the VIP(s) only after the HANA resource has been promoted -- name: "SAP HA Prepare Pacemaker - Add order constraint: VIP starts after DB is promoted" +- name: "SAP HA Prepare Pacemaker - Add order constraint: Primary VIP starts after DB is promoted" ansible.builtin.set_fact: __sap_ha_pacemaker_cluster_constraints_order: "{{ __sap_ha_pacemaker_cluster_constraints_order + [__constraint_order_vip] }}" vars: @@ -11,11 +11,10 @@ id: "{{ sap_ha_pacemaker_cluster_hana_resource_clone_name }}" action: promote resource_then: - id: "{{ __sap_ha_pacemaker_cluster_vip_resource_id }}" + id: "{{ vip_list_item.key }}" action: start when: - __constraint_order_vip.resource_then not in (__sap_ha_pacemaker_cluster_constraints_order | map(attribute='resource_then')) - - vip_list_item.key in __sap_ha_pacemaker_cluster_hana_primary_synonyms # The primary VIP only runs where HANA is promoted - name: "SAP HA Prepare Pacemaker - Add colocation constraint: Primary VIP runs where HANA is promoted" @@ -27,13 +26,12 @@ id: "{{ sap_ha_pacemaker_cluster_hana_resource_clone_name }}" role: promoted resource_follower: - id: "{{ __sap_ha_pacemaker_cluster_vip_resource_id }}" + id: "{{ sap_ha_pacemaker_cluster_vip_hana_primary_resource_name }}" options: - name: score value: 2000 when: - __constraint_colo_vip.resource_follower not in (__sap_ha_pacemaker_cluster_constraints_colocation | map(attribute='resource_follower')) - - vip_list_item.key in __sap_ha_pacemaker_cluster_hana_primary_synonyms # The secondary VIP only runs where HANA is UNpromoted - name: "SAP HA Prepare Pacemaker - Add colocation constraint: Read-only VIP runs where HANA is not promoted" @@ -45,10 +43,11 @@ id: "{{ sap_ha_pacemaker_cluster_hana_resource_clone_name }}" role: unpromoted resource_follower: - id: "{{ __sap_ha_pacemaker_cluster_vip_resource_id }}" + id: "{{ sap_ha_pacemaker_cluster_vip_hana_secondary_resource_name }}" options: - name: score value: 2000 when: - __constraint_colo_vip.resource_follower not in (__sap_ha_pacemaker_cluster_constraints_colocation | map(attribute='resource_follower')) - - vip_list_item.key in __sap_ha_pacemaker_cluster_hana_secondary_synonyms + - sap_ha_pacemaker_cluster_vip_hana_secondary_ip_address is defined + - sap_ha_pacemaker_cluster_vip_hana_secondary_ip_address != '' diff --git a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_vip_constraints_netweaver.yml b/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_vip_constraints_netweaver.yml deleted file mode 100644 index 4a0636797..000000000 --- a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_vip_constraints_netweaver.yml +++ /dev/null @@ -1,78 +0,0 @@ ---- -# Reminder: This file is included in a loop over a dictionary. - -################################################## -# NetWeaver ASCS -################################################## - -# Start the VIP only after the ASCS resource has been started -- name: "SAP HA Prepare Pacemaker - Add order constraint: ASCS VIP starts after NetWeaver ASCS is started" - ansible.builtin.set_fact: - __sap_ha_pacemaker_cluster_constraints_order: "{{ __sap_ha_pacemaker_cluster_constraints_order + [__constraint_order_vip] }}" - vars: - __constraint_order_vip: - resource_first: - id: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ascs_sapinstance_resource_name }}" - action: start - resource_then: - id: "{{ __sap_ha_pacemaker_cluster_vip_resource_id }}" - action: start - when: - - __constraint_order_vip.resource_then not in (__sap_ha_pacemaker_cluster_constraints_order | map(attribute='resource_then')) - - vip_list_item.key in __sap_ha_pacemaker_cluster_nwas_ascs_synonyms - -# The VIP only runs where the ASCS resource is running -- the VIP in the the group -#- name: "SAP HA Prepare Pacemaker - Add colocation constraint: VIP runs where NetWeaver ASCS is running" -# ansible.builtin.set_fact: -# __sap_ha_pacemaker_cluster_constraints_colocation: "{{ __sap_ha_pacemaker_cluster_constraints_colocation + [__constraint_colo_vip] }}" -# vars: -# __constraint_colo_vip: -# resource_leader: -# id: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ascs_sapinstance_resource_name }}" -# role: started -# resource_follower: -# id: "{{ __sap_ha_pacemaker_cluster_vip_resource_id }}" -# options: -# - name: score -# value: 2000 -# when: -# - __constraint_colo_vip.resource_follower not in (__sap_ha_pacemaker_cluster_constraints_colocation | map(attribute='resource_follower')) -# - vip_list_item.key in __sap_ha_pacemaker_cluster_nwas_ascs_synonyms - -################################################## -# NetWeaver ERS -################################################## - -# Start the VIP only after the ERS resource has been started -- name: "SAP HA Prepare Pacemaker - Add order constraint: ERS VIP starts after NetWeaver ERS is started" - ansible.builtin.set_fact: - __sap_ha_pacemaker_cluster_constraints_order: "{{ __sap_ha_pacemaker_cluster_constraints_order + [__constraint_order_vip] }}" - vars: - __constraint_order_vip: - resource_first: - id: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ers_sapinstance_resource_name }}" - action: start - resource_then: - id: "{{ __sap_ha_pacemaker_cluster_vip_resource_id }}" - action: start - when: - - __constraint_order_vip.resource_then not in (__sap_ha_pacemaker_cluster_constraints_order | map(attribute='resource_then')) - - vip_list_item.key in __sap_ha_pacemaker_cluster_nwas_ers_synonyms - -# The VIP only runs where the ERS resource is running -#- name: "SAP HA Prepare Pacemaker - Add colocation constraint: VIP runs where NetWeaver ERS is running" -# ansible.builtin.set_fact: -# __sap_ha_pacemaker_cluster_constraints_colocation: "{{ __sap_ha_pacemaker_cluster_constraints_colocation + [__constraint_colo_vip] }}" -# vars: -# __constraint_colo_vip: -# resource_leader: -# id: "{{ sap_ha_pacemaker_cluster_netweaver_abap_ers_sapinstance_resource_name }}" -# role: started -# resource_follower: -# id: "{{ __sap_ha_pacemaker_cluster_vip_resource_id }}" -# options: -# - name: score -# value: 2000 -# when: -# - __constraint_colo_vip.resource_follower not in (__sap_ha_pacemaker_cluster_constraints_colocation | map(attribute='resource_follower')) -# - vip_list_item.key in __sap_ha_pacemaker_cluster_nwas_ers_synonyms diff --git a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_vip_resources_default.yml b/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_vip_resources_default.yml index 3e2b16235..fda53ca9b 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_vip_resources_default.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_vip_resources_default.yml @@ -2,16 +2,19 @@ # Reminder: This file is included in a loop over a dictionary. # VIP resource definition itself -- name: "SAP HA Prepare Pacemaker - Add resource: VIP {{ vip_list_item.key }}" +- name: "SAP HA Prepare Pacemaker - Add resource: VIP {{ vip_list_item.key }} ({{ sap_ha_pacemaker_cluster_vip_resource_agent }})" ansible.builtin.set_fact: __sap_ha_pacemaker_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives + [__resource_vip] }}" vars: __resource_vip: - id: "{{ __sap_ha_pacemaker_cluster_vip_resource_id }}" + id: "{{ vip_list_item.key }}" agent: "{{ sap_ha_pacemaker_cluster_vip_resource_agent }}" instance_attrs: - attrs: - name: ip value: "{{ vip_list_item.value | quote }}" + - name: nic + value: "{{ sap_ha_pacemaker_cluster_vip_client_interface }}" when: - __sap_ha_pacemaker_cluster_vip_resource_id not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) + - '"IPaddr2" in sap_ha_pacemaker_cluster_vip_resource_agent' diff --git a/roles/sap_ha_pacemaker_cluster/tasks/import_hacluster_vars_from_inventory.yml b/roles/sap_ha_pacemaker_cluster/tasks/import_hacluster_vars_from_inventory.yml new file mode 100644 index 000000000..a2ca8de87 --- /dev/null +++ b/roles/sap_ha_pacemaker_cluster/tasks/import_hacluster_vars_from_inventory.yml @@ -0,0 +1,94 @@ +--- +# If there are "ha_cluster" Linux System Role parameters already defined in the +# inventory, we will include these custom specifications and they take precedence. + +# Only parameters which need to be adjusted or enhanced by the SAP HA role +# need to be included here. + + +### Take the following template to add additional parameters to be inherited: +# - name: "SAP HA Prepare Pacemaker - Register ha_cluster_" +# ansible.builtin.set_fact: +# __sap_ha_pacemaker_cluster_: "{{ ha_cluster_ }}" +# when: ha_cluster_ is defined + + +# ha_cluster +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Register parameter 'ha_cluster'" + when: ha_cluster is defined + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_ha_cluster: "{{ ha_cluster }}" + +# ha_cluster_cluster_name +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Register parameter 'ha_cluster_cluster_name'" + when: ha_cluster_cluster_name is defined + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_cluster_name: "{{ ha_cluster_cluster_name }}" + +# ha_cluster_cluster_properties +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Register parameter 'ha_cluster_cluster_properties'" + when: ha_cluster_cluster_properties is defined + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_cluster_properties: "{{ ha_cluster_cluster_properties }}" + +#__sap_ha_pacemaker_cluster_resource_groups ha_cluster_constraints_colocation +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Register parameter 'ha_cluster_constraints_colocation'" + when: ha_cluster_constraints_colocation is defined + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_constraints_colocation: "{{ ha_cluster_constraints_colocation }}" + +# ha_cluster_constraints_location +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Register parameter 'ha_cluster_constraints_location'" + when: ha_cluster_constraints_location is defined + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_constraints_location: "{{ ha_cluster_constraints_location }}" + +# ha_cluster_constraints_order +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Register parameter 'ha_cluster_constraints_order'" + when: ha_cluster_constraints_order is defined + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_constraints_order: "{{ ha_cluster_constraints_order }}" + +# ha_cluster_extra_packages +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Register parameter 'ha_cluster_extra_packages'" + when: ha_cluster_extra_packages is defined + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_extra_packages: "{{ ha_cluster_extra_packages }}" + +# ha_cluster_fence_agent_packages +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Register parameter 'ha_cluster_fence_agent_packages'" + when: ha_cluster_fence_agent_packages is defined + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_fence_agent_packages: "{{ ha_cluster_fence_agent_packages }}" + +# ha_cluster_hacluster_password +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Register parameter 'ha_cluster_repos'" + when: ha_cluster_hacluster_password is defined + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_hacluster_user_password: "{{ ha_cluster_hacluster_password }}" + no_log: true # handle credentials with care + +# ha_cluster_repos +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Register parameter 'ha_cluster_repos'" + when: ha_cluster_repos is defined + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_repos: "{{ ha_cluster_repos }}" + +# ha_cluster_resource_clones +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Register parameter 'ha_cluster_resource_clones'" + when: ha_cluster_resource_clones is defined + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_resource_clones: "{{ ha_cluster_resource_clones }}" + +# ha_cluster_resource_groups +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Register parameter 'ha_cluster_resource_groups'" + when: ha_cluster_resource_groups is defined + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_resource_groups: "{{ ha_cluster_resource_groups }}" + +# ha_cluster_resource_primitives +- name: "SAP HA Prepare Pacemaker - (ha_cluster) Register parameter 'ha_cluster_resource_primitives'" + when: ha_cluster_resource_primitives is defined + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_resource_primitives: "{{ ha_cluster_resource_primitives }}" + no_log: true # be paranoid, there could be credentials in it diff --git a/roles/sap_ha_pacemaker_cluster/tasks/include_construct_vip_resources.yml b/roles/sap_ha_pacemaker_cluster/tasks/include_construct_vip_resources.yml index bb768bdd4..2ef69df6e 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/include_construct_vip_resources.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/include_construct_vip_resources.yml @@ -2,50 +2,68 @@ # The VIP resource construction files are included in a loop to allow # for multiple IPs to be configured in cluster resources +- name: "SAP HA Prepare Pacemaker - Make a list of potential VIP definitions" + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_all_vip_fact: + hana_scaleup_perf: "{{ + { + sap_ha_pacemaker_cluster_vip_hana_primary_resource_name: sap_ha_pacemaker_cluster_vip_hana_primary_ip_address | regex_replace('/.*', ''), + sap_ha_pacemaker_cluster_vip_hana_secondary_resource_name: sap_ha_pacemaker_cluster_vip_hana_secondary_ip_address | regex_replace('/.*', '') + } }}" + nwas_abap_ascs_ers: "{{ + { + sap_ha_pacemaker_cluster_vip_nwas_abap_ascs_resource_name: sap_ha_pacemaker_cluster_vip_nwas_abap_ascs_ip_address | regex_replace('/.*', ''), + sap_ha_pacemaker_cluster_vip_nwas_abap_ers_resource_name: sap_ha_pacemaker_cluster_vip_nwas_abap_ers_ip_address | regex_replace('/.*', '') + } }}" + nwas_abap_pas_aas: "{{ + { + sap_ha_pacemaker_cluster_vip_nwas_abap_pas_resource_name: sap_ha_pacemaker_cluster_vip_nwas_abap_pas_ip_address | regex_replace('/.*', ''), + sap_ha_pacemaker_cluster_vip_nwas_abap_aas_resource_name: sap_ha_pacemaker_cluster_vip_nwas_abap_aas_ip_address | regex_replace('/.*', '') + } }}" + +- name: "SAP HA Prepare Pacemaker - Combine VIP parameters" + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_vip_resource_definition: + "{{ __sap_ha_pacemaker_cluster_vip_resource_definition | default({}) + | combine(__sap_ha_pacemaker_cluster_all_vip_fact[vip_item]) }}" + loop: "{{ sap_ha_pacemaker_cluster_host_type }}" + loop_control: + loop_var: vip_item + + +# Repeat the VIP resource definition in a loop over the above combined possible parameters. - name: "SAP HA Prepare Pacemaker - Include variable construction for standard VIP resources" ansible.builtin.include_tasks: construct_vars_vip_resources_default.yml - loop: "{{ query('dict', sap_ha_pacemaker_cluster_vip_address) }}" + loop: "{{ query('dict', __sap_ha_pacemaker_cluster_vip_resource_definition) }}" loop_control: index_var: loop_index loop_var: vip_list_item - vars: - __sap_ha_pacemaker_cluster_vip_resource_id: "{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" + label: "{{ vip_list_item.key }} - {{ vip_list_item.value }}" when: - - __sap_ha_pacemaker_cluster_platform not in __sap_ha_pacemaker_cluster_supported_platforms - - (vip_list_item.value is defined) and (vip_list_item.value != '') + - sap_ha_pacemaker_cluster_vip_method == 'ipaddr' + - vip_list_item.value | length > 0 + - name: "SAP HA Prepare Pacemaker - Include variable construction for platform VIP resources" ansible.builtin.include_tasks: "platform/construct_vars_vip_resources_{{ __sap_ha_pacemaker_cluster_platform }}.yml" - loop: "{{ query('dict', sap_ha_pacemaker_cluster_vip_address) }}" + loop: "{{ query('dict', __sap_ha_pacemaker_cluster_vip_resource_definition) }}" loop_control: index_var: loop_index loop_var: vip_list_item + label: "{{ vip_list_item.key }} - {{ vip_list_item.value }}" when: - - __sap_ha_pacemaker_cluster_platform in __sap_ha_pacemaker_cluster_supported_platforms - - (vip_list_item.value is defined) and (vip_list_item.value != '') + - sap_ha_pacemaker_cluster_vip_method != 'ipaddr' + - vip_list_item.value | length > 0 + - name: "SAP HA Prepare Pacemaker - Include variable construction for SAP Hana VIP constraints" ansible.builtin.include_tasks: file: construct_vars_vip_constraints_hana.yml - loop: "{{ query('dict', sap_ha_pacemaker_cluster_vip_address) }}" + loop: "{{ query('dict', __sap_ha_pacemaker_cluster_vip_resource_definition) }}" loop_control: index_var: loop_index loop_var: vip_list_item - vars: - __sap_ha_pacemaker_cluster_vip_resource_id: "{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" + label: "{{ vip_list_item.key }} - {{ vip_list_item.value }}" when: - - (vip_list_item.value is defined) and (vip_list_item.value != '') - sap_ha_pacemaker_cluster_host_type | select('search', 'hana') | length > 0 - -- name: "SAP HA Prepare Pacemaker - Include variable construction for SAP NetWeaver VIP constraints" - ansible.builtin.include_tasks: - file: construct_vars_vip_constraints_netweaver.yml - loop: "{{ query('dict', sap_ha_pacemaker_cluster_vip_address) }}" - loop_control: - index_var: loop_index - loop_var: vip_list_item - vars: - __sap_ha_pacemaker_cluster_vip_resource_id: "{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" - when: - - (vip_list_item.value is defined) and (vip_list_item.value != '') - - sap_ha_pacemaker_cluster_host_type | select('search', 'nwas') | length > 0 + - vip_list_item.value != '' diff --git a/roles/sap_ha_pacemaker_cluster/tasks/include_vars_common.yml b/roles/sap_ha_pacemaker_cluster/tasks/include_vars_common.yml index ab3e1bb74..f132a6738 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/include_vars_common.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/include_vars_common.yml @@ -7,6 +7,24 @@ ansible.builtin.setup: gather_subset: hardware,interfaces +# Multi-NIC: +# Find out if there is more than one interface present, this will +# be used for determining the target NIC for VIP configurations. +# Assumption: The local loopback "lo" is always in the list. +- name: "SAP HA Prepare Pacemaker - Set multi-NIC when more than one interface is found" + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_nic_multi_bool: true + when: + - ansible_interfaces | length > 2 + +- name: "SAP HA Prepare Pacemaker - Set interface name when only one interface is present" + ansible.builtin.set_fact: + sap_ha_pacemaker_cluster_vip_client_interface: "{{ ansible_default_ipv4.interface }}" + when: + - not __sap_ha_pacemaker_cluster_nic_multi_bool + - sap_ha_pacemaker_cluster_vip_client_interface == '' + + # Include vars files based on the environment. # Respect order for potential variable precedence. - name: "SAP HA Prepare Pacemaker - Include environment specific variables" diff --git a/roles/sap_ha_pacemaker_cluster/tasks/include_vars_netweaver.yml b/roles/sap_ha_pacemaker_cluster/tasks/include_vars_nwas.yml similarity index 100% rename from roles/sap_ha_pacemaker_cluster/tasks/include_vars_netweaver.yml rename to roles/sap_ha_pacemaker_cluster/tasks/include_vars_nwas.yml diff --git a/roles/sap_ha_pacemaker_cluster/tasks/main.yml b/roles/sap_ha_pacemaker_cluster/tasks/main.yml index e05a72ea4..a235bd0ec 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/main.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/main.yml @@ -21,8 +21,8 @@ # Make sure that all parameters already set for 'ha_cluster' are also inherited. # Add to this file a task for EACH parameter which this SAP cluster role # supports. -- name: "SAP HA Prepare Pacemaker - Include tasks for checking 'ha_cluster' predefinitions" - ansible.builtin.import_tasks: ascertain_ha_cluster_in_inventory.yml +- name: "SAP HA Prepare Pacemaker - Include tasks from 'ha_cluster' role definitions" + ansible.builtin.import_tasks: import_hacluster_vars_from_inventory.yml - name: "SAP HA Prepare Pacemaker - Include facts and common variables" ansible.builtin.import_tasks: include_vars_common.yml @@ -53,23 +53,23 @@ ansible.builtin.include_tasks: file: construct_vars_hana_common.yml when: - - "'hana' in sap_ha_pacemaker_cluster_host_type[0]" + - sap_ha_pacemaker_cluster_host_type | select('search', 'hana') | length > 0 - name: "SAP HA Prepare Pacemaker - Include variable construction for SAP HANA Scale-up" ansible.builtin.include_tasks: file: construct_vars_hana_scaleup.yml when: - - "'hana_scaleup' in sap_ha_pacemaker_cluster_host_type[0]" + - sap_ha_pacemaker_cluster_host_type | select('search', 'hana_scaleup') | length > 0 - name: "SAP HA Prepare Pacemaker - Include variable construction for SAP NetWeaver common" ansible.builtin.include_tasks: - file: construct_vars_netweaver_common.yml + file: construct_vars_nwas_common.yml when: - - "'nwas_abap' in sap_ha_pacemaker_cluster_host_type[0]" + - sap_ha_pacemaker_cluster_host_type | select('search', 'nwas_abap') | length > 0 - name: "SAP HA Prepare Pacemaker - Include variable construction for SAP NetWeaver ABAP ASCS/ERS" ansible.builtin.include_tasks: - file: construct_vars_netweaver_abap_ascs_ers.yml + file: construct_vars_nwas_abap_ascs_ers.yml loop: "{{ sap_ha_pacemaker_cluster_host_type }}" loop_control: loop_var: nwas_build_item @@ -78,7 +78,7 @@ - name: "SAP HA Prepare Pacemaker - Include variable construction for SAP NetWeaver ABAP PAS/AAS" ansible.builtin.include_tasks: - file: construct_vars_netweaver_abap_pas_aas.yml + file: construct_vars_nwas_abap_pas_aas.yml loop: "{{ sap_ha_pacemaker_cluster_host_type }}" loop_control: loop_var: nwas_build_item @@ -87,13 +87,24 @@ - name: "SAP HA Prepare Pacemaker - Include variable construction for SAP NetWeaver Java SCS/ERS" ansible.builtin.include_tasks: - file: construct_vars_netweaver_java_scs_ers.yml + file: construct_vars_nwas_java_scs_ers.yml loop: "{{ sap_ha_pacemaker_cluster_host_type }}" loop_control: loop_var: nwas_build_item when: - "'nwas_java' in nwas_build_item" +# All of the SAP HA role constructed parameters must be translated to +# 'ha_cluster' Linux System Role parameters. +- name: "SAP HA Prepare Pacemaker - Translate all parameters to 'ha_cluster' input variables" + ansible.builtin.include_tasks: + file: construct_final_hacluster_vars.yml + + +########################################################## +# BLOCK which covers actual changes on the target systems +########################################################## + - name: "SAP HA Install Pacemaker - Block with actual changes" block: @@ -111,6 +122,7 @@ # for instance cloud-init services on cloud platforms - name: "SAP HA Install Pacemaker - Stop and disable services" when: sap_ha_pacemaker_cluster_disable_services is defined + register: __sap_ha_pacemaker_cluster_disable_services ansible.builtin.service: name: "{{ service_item }}" enabled: false @@ -119,20 +131,9 @@ loop_control: loop_var: service_item label: "{{ service_item }}" - - # Before we are ready to call the ha_cluster role, we want to validate - # that the minimum required parameters are defined and not empty. - # TODO: make this smarter, currently all these vars are pre-defined anyway - - name: "SAP HA Install Pacemaker - Validate parameters for 'ha_cluster' role input" - ansible.builtin.assert: - that: - - __sap_ha_pacemaker_cluster_cluster_properties is defined - - __sap_ha_pacemaker_cluster_extra_packages is defined - - __sap_ha_pacemaker_cluster_resource_primitives is defined - - __sap_ha_pacemaker_cluster_resource_clones is defined - - __sap_ha_pacemaker_cluster_constraints_order is defined - - __sap_ha_pacemaker_cluster_constraints_colocation is defined - fail_msg: "Cluster build parameter construction has failed for this parameter." + failed_when: + - __sap_ha_pacemaker_cluster_disable_services.failed + - '"Could not find the requested service" not in __sap_ha_pacemaker_cluster_disable_services.msg' - name: "SAP HA Install Pacemaker - Query if CIB already exists" ansible.builtin.command: @@ -162,28 +163,16 @@ apply: tags: ha_cluster no_log: true # some parameters contain secrets - no_log: true # some parameters contain secrets - vars: - __ha_cluster_repos: "{{ __sap_ha_pacemaker_cluster_repos }}" - ha_cluster_cluster_name: "{{ __sap_ha_pacemaker_cluster_cluster_name }}" - ha_cluster_constraints_order: "{{ __sap_ha_pacemaker_cluster_constraints_order }}" - ha_cluster_constraints_colocation: "{{ __sap_ha_pacemaker_cluster_constraints_colocation }}" - ha_cluster_cluster_properties: "{{ __sap_ha_pacemaker_cluster_cluster_properties }}" - ha_cluster_extra_packages: "{{ __sap_ha_pacemaker_cluster_extra_packages }}" - ha_cluster_fence_agent_packages: "{{ __sap_ha_pacemaker_cluster_fence_agent_packages }}" - ha_cluster_hacluster_password: "{{ __sap_ha_pacemaker_cluster_hacluster_password }}" - ha_cluster_properties: "{{ __sap_ha_pacemaker_cluster_cluster_properties }}" - ha_cluster_resource_clones: "{{ __sap_ha_pacemaker_cluster_resource_clones }}" - ha_cluster_resource_groups: "{{ __sap_ha_pacemaker_cluster_resource_groups }}" - ha_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives }}" tags: ha_cluster - # Resource defaults can currently not be updated through ha_cluster - # role parameters, and thus need to be added. + # Resource defaults settings were added to "ha_cluster" in Apr 2023 (GH version 1.9.0) + # https://github.com/linux-system-roles/ha_cluster#ha_cluster_resource_defaults + # Keeping separate for compatibility with older versions of the ha_cluster role. + # TODO: Change resource defaults update to "ha_cluster" native syntax. - name: "SAP HA Install Pacemaker - Check resource defaults" ansible.builtin.command: cmd: | - pcs resource defaults config + {{ __sap_ha_pacemaker_cluster_command.resource_defaults_show }} register: __sap_ha_pacemaker_cluster_check_resource_defaults run_once: true changed_when: false @@ -192,10 +181,12 @@ - name: "SAP HA Install Pacemaker - Update resource default attributes" when: - item.key ~ '=' ~ item.value not in __sap_ha_pacemaker_cluster_check_resource_defaults.stdout + - __sap_ha_pacemaker_cluster_resource_defaults is defined + - __sap_ha_pacemaker_cluster_resource_defaults | length > 0 ansible.builtin.command: cmd: | - pcs resource defaults update {{ item.key }}={{ item.value }} - loop: "{{ sap_ha_pacemaker_cluster_resource_defaults | dict2items }}" + {{ __sap_ha_pacemaker_cluster_command.resource_defaults_update }} {{ item.key }}={{ item.value }} + loop: "{{ __sap_ha_pacemaker_cluster_resource_defaults | dict2items }}" loop_control: label: "{{ item.key }}={{ item.value }}" run_once: true @@ -209,6 +200,15 @@ when: - sap_ha_pacemaker_cluster_host_type | select('search', 'hana') | length > 0 + - name: "SAP HA Install Pacemaker - Include NetWeaver ASCS/ERS post installation" + ansible.builtin.include_tasks: + file: configure_nwas_ascs_ers_postinstallation.yml + apply: + tags: nwas_postinst + tags: nwas_postinst + when: + - sap_ha_pacemaker_cluster_host_type | select('search', 'nwas_abap') | length > 0 + ### END OF BLOCK: prerequisite changes and cluster setup # Save all the constructed cluster parameters into a vars file. diff --git a/roles/sap_ha_pacemaker_cluster/tasks/platform/ascertain_platform_type.yml b/roles/sap_ha_pacemaker_cluster/tasks/platform/ascertain_platform_type.yml index b35399f91..a12ee9c30 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/platform/ascertain_platform_type.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/platform/ascertain_platform_type.yml @@ -46,7 +46,8 @@ - name: "SAP HA Prepare Pacemaker - Check if platform is Amazon Web Services EC2 Virtual Server" when: - - ansible_system_vendor == 'Amazon EC2' + - '"amazon" in ansible_system_vendor | lower + or "amazon" in ansible_product_name | lower' ansible.builtin.set_fact: __sap_ha_pacemaker_cluster_platform: cloud_aws_ec2_vs @@ -97,12 +98,12 @@ ansible.builtin.set_fact: __sap_ha_pacemaker_cluster_platform: cloud_ibmcloud_powervs -#- name: "SAP HA Prepare Pacemaker - Check if platform is IBM PowerVC" -# when: -# - ansible_architecture == "ppc64le" -# - '"ibmcloud" not in __sap_ha_pacemaker_cluster_power_rsct_hscid.stdout' -# ansible.builtin.set_fact: -# __sap_ha_pacemaker_cluster_platform: hyp_ibmpower_vm +- name: "SAP HA Prepare Pacemaker - Check if platform is IBM PowerVM" + when: + - ansible_architecture == "ppc64le" + - '"ibmcloud" not in __sap_ha_pacemaker_cluster_power_rsct_hscid.stdout' + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_platform: hyp_ibmpower_vm #- name: "SAP HA Prepare Pacemaker - Check if platform is VMware vSphere" # when: @@ -110,18 +111,6 @@ # ansible.builtin.set_fact: # __sap_ha_pacemaker_cluster_platform: hyp_vmware_vsphere_vm -# Call tasks to discover information that is needed as input for any further steps. -# Run this before including the platform vars in order to build vars based on the -# discovered data. -- name: "SAP HA Prepare Pacemaker - Include platform specific information collection" - when: __sap_ha_pacemaker_cluster_platform_info is file - ansible.builtin.include_tasks: - file: "{{ item }}" - loop: - - "register_sysinfo_{{ __sap_ha_pacemaker_cluster_platform }}.yml" - vars: - __sap_ha_pacemaker_cluster_platform_info: "{{ role_path }}/tasks/{{ item }}" - - name: "SAP HA Prepare Pacemaker - Include platform specific tasks - MS Azure VM - Ensure socat binary installed" ansible.builtin.package: name: @@ -137,6 +126,6 @@ ansible.builtin.include_tasks: file: "{{ item }}" loop: - - "register_sysinfo_{{ __sap_ha_pacemaker_cluster_platform }}.yml" + - "platform/register_sysinfo_{{ __sap_ha_pacemaker_cluster_platform }}.yml" vars: __sap_ha_pacemaker_cluster_platform_info: "{{ role_path }}/tasks/{{ item }}" diff --git a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_aws_ec2_vs.yml b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_aws_ec2_vs.yml index 6e99cef8f..0a178b04e 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_aws_ec2_vs.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_aws_ec2_vs.yml @@ -4,17 +4,18 @@ - name: "SAP HA Prepare Pacemaker - ipaddr resource agent - Add resource: OS network interface Virtual IP (dev/test only)" ansible.builtin.set_fact: __sap_ha_pacemaker_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives + [__resource_vip] }}" - __sap_ha_pacemaker_cluster_vip_resource_id: "{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" vars: __resource_vip: - id: "{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" + id: "{{ vip_list_item.key }}" agent: "{{ __sap_ha_pacemaker_cluster_available_vip_agents[sap_ha_pacemaker_cluster_vip_method].agent }}" instance_attrs: - attrs: - name: ip value: "{{ vip_list_item.value }}" + - name: nic + value: "{{ sap_ha_pacemaker_cluster_vip_client_interface }}" when: - - sap_ha_pacemaker_cluster_vip_resource_name ~ '_' ~ vip_list_item.key not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) + - vip_list_item.key not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) - (sap_ha_pacemaker_cluster_vip_method == 'ipaddr') or (__sap_ha_pacemaker_cluster_available_vip_agents[sap_ha_pacemaker_cluster_vip_method].with is defined and 'ipaddr' in __sap_ha_pacemaker_cluster_available_vip_agents[sap_ha_pacemaker_cluster_vip_method].with) @@ -24,37 +25,35 @@ __sap_ha_pacemaker_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives + [__resource_vip] }}" vars: __resource_vip: - id: "pri{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" + id: "pri_{{ vip_list_item.key }}" agent: "{{ __sap_ha_pacemaker_cluster_available_vip_agents[sap_ha_pacemaker_cluster_vip_method].agent }}" instance_attrs: - attrs: - name: secondary_private_ip value: "{{ vip_list_item.value }}" when: - - ('pri' ~ sap_ha_pacemaker_cluster_vip_resource_name ~ '_' ~ vip_list_item.key) not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) + - ('pri_' ~ vip_list_item.key) not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) - sap_ha_pacemaker_cluster_vip_method == 'awsvip' -- name: "SAP HA Prepare Pacemaker - awsvip resource agent - Add resource group for VIP resources" +- name: "SAP HA Prepare Pacemaker - awsvip resource agent - Add resource group for VIP resources (dev/test only)" ansible.builtin.set_fact: __sap_ha_pacemaker_cluster_resource_groups: "{{ __sap_ha_pacemaker_cluster_resource_groups + [__vip_group] }}" - __sap_ha_pacemaker_cluster_vip_resource_id: "{{ sap_ha_pacemaker_cluster_vip_resource_group_name }}_{{ vip_list_item.key }}" vars: __vip_group: id: "{{ sap_ha_pacemaker_cluster_vip_resource_group_name }}_{{ vip_list_item.key }}" resource_ids: - - "{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" - - "pri{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" + - "{{ vip_list_item.key }}" + - "pri_{{ vip_list_item.key }}" when: - __vip_group.id is not in (__sap_ha_pacemaker_cluster_resource_groups | map(attribute='id')) - sap_ha_pacemaker_cluster_vip_method in ['awsvip'] -- name: "SAP HA Prepare Pacemaker - aws_vpc_move_ip resource agent - Add resource: AWS VIP routing" +- name: "SAP HA Prepare Pacemaker - aws_vpc_move_ip resource agent - Add resource: AWS VIP OverlayIP" ansible.builtin.set_fact: __sap_ha_pacemaker_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives + [__resource_vip] }}" - __sap_ha_pacemaker_cluster_vip_resource_id: "{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" vars: __resource_vip: - id: "{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" + id: "{{ vip_list_item.key }}" agent: "{{ __sap_ha_pacemaker_cluster_available_vip_agents[sap_ha_pacemaker_cluster_vip_method].agent }}" instance_attrs: - attrs: @@ -63,7 +62,7 @@ - name: interface value: "{{ sap_ha_pacemaker_cluster_vip_client_interface }}" - name: routing_table - value: "{{ sap_ha_pacemaker_cluster_vip_update_rt | join(',') }}" + value: "{{ sap_ha_pacemaker_cluster_aws_vip_update_rt }}" when: - - (sap_ha_pacemaker_cluster_vip_resource_name ~ '_' ~ vip_list_item.key) not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) + - vip_list_item.key not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) - sap_ha_pacemaker_cluster_vip_method == 'aws_vpc_move_ip' diff --git a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_gcp_ce_vm.yml b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_gcp_ce_vm.yml index 5434e770b..39272c9a6 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_gcp_ce_vm.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_gcp_ce_vm.yml @@ -4,17 +4,20 @@ - name: "SAP HA Prepare Pacemaker - ipaddr resource agent - Add resource: OS network interface Virtual IP" ansible.builtin.set_fact: __sap_ha_pacemaker_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives + [__resource_vip] }}" - __sap_ha_pacemaker_cluster_vip_resource_id: "{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" vars: __resource_vip: - id: "{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" + id: "{{ vip_list_item.key }}" agent: "{{ __sap_ha_pacemaker_cluster_available_vip_agents['ipaddr'].agent }}" instance_attrs: - attrs: - name: ip value: "{{ vip_list_item.value }}" + - name: cidr_netmask + value: 32 + - name: nic + value: "{{ sap_ha_pacemaker_cluster_vip_client_interface }}" when: - - sap_ha_pacemaker_cluster_vip_resource_name ~ '_' ~ vip_list_item.key not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) + - vip_list_item.key not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) - (sap_ha_pacemaker_cluster_vip_method == 'ipaddr') or (__sap_ha_pacemaker_cluster_available_vip_agents[sap_ha_pacemaker_cluster_vip_method].with is defined and 'ipaddr' in __sap_ha_pacemaker_cluster_available_vip_agents[sap_ha_pacemaker_cluster_vip_method].with) @@ -22,10 +25,9 @@ - name: "SAP HA Prepare Pacemaker - haproxy resource agent - Add resource: Google Cloud Load Balancing Internal passthrough Network Load Balancer (NLB L-4) for VIP routing when SAP HANA scale-up HA" ansible.builtin.set_fact: __sap_ha_pacemaker_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives + [__health_check] }}" - __sap_ha_pacemaker_cluster_vip_resource_id: "{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" vars: __health_check: - id: "hc_{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" + id: "hc_{{ vip_list_item.key }}" agent: "{{ __sap_ha_pacemaker_cluster_available_vip_agents[sap_ha_pacemaker_cluster_vip_method].agent }}" operations: - action: monitor @@ -36,6 +38,6 @@ value: 20 when: - __health_check.id is not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) - - ('hc_' ~ sap_ha_pacemaker_cluster_vip_resource_name ~ '_' ~ vip_list_item.key) not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) + - ('hc_' + vip_list_item.key) not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) - sap_ha_pacemaker_cluster_vip_method == 'gcp_nlb_reserved_ip_haproxy' - sap_ha_pacemaker_cluster_host_type | select('search', 'hana') | length > 0 diff --git a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_ibmcloud_powervs.yml b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_ibmcloud_powervs.yml index 306036c53..97b662d67 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_ibmcloud_powervs.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_ibmcloud_powervs.yml @@ -4,17 +4,18 @@ - name: "SAP HA Prepare Pacemaker - ipaddr resource agent - Add resource: OS network interface Virtual IP" ansible.builtin.set_fact: __sap_ha_pacemaker_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives + [__resource_vip] }}" - __sap_ha_pacemaker_cluster_vip_resource_id: "{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" vars: __resource_vip: - id: "{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" + id: "{{ vip_list_item.key }}" agent: "{{ __sap_ha_pacemaker_cluster_available_vip_agents['ipaddr'].agent }}" instance_attrs: - attrs: - name: ip value: "{{ vip_list_item.value }}" + - name: nic + value: "{{ sap_ha_pacemaker_cluster_vip_client_interface }}" when: - - sap_ha_pacemaker_cluster_vip_resource_name ~ '_' ~ vip_list_item.key not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) + - vip_list_item.key not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) - (sap_ha_pacemaker_cluster_vip_method == 'ipaddr') or (__sap_ha_pacemaker_cluster_available_vip_agents[sap_ha_pacemaker_cluster_vip_method].with is defined and 'ipaddr' in __sap_ha_pacemaker_cluster_available_vip_agents[sap_ha_pacemaker_cluster_vip_method].with) diff --git a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_msazure_vm.yml b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_msazure_vm.yml index de0a728ed..117a8439f 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_msazure_vm.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_msazure_vm.yml @@ -4,17 +4,18 @@ - name: "SAP HA Prepare Pacemaker - ipaddr resource agent - Add resource: OS network interface Virtual IP" ansible.builtin.set_fact: __sap_ha_pacemaker_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives + [__resource_vip] }}" - __sap_ha_pacemaker_cluster_vip_resource_id: "{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" vars: __resource_vip: - id: "{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" + id: "{{ vip_list_item.key }}" agent: "{{ __sap_ha_pacemaker_cluster_available_vip_agents['ipaddr'].agent }}" instance_attrs: - attrs: - name: ip value: "{{ vip_list_item.value }}" + - name: nic + value: "{{ sap_ha_pacemaker_cluster_vip_client_interface }}" when: - - sap_ha_pacemaker_cluster_vip_resource_name ~ '_' ~ vip_list_item.key not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) + - vip_list_item.key not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) - (sap_ha_pacemaker_cluster_vip_method == 'ipaddr') or (__sap_ha_pacemaker_cluster_available_vip_agents[sap_ha_pacemaker_cluster_vip_method].with is defined and 'ipaddr' in __sap_ha_pacemaker_cluster_available_vip_agents[sap_ha_pacemaker_cluster_vip_method].with) @@ -28,16 +29,15 @@ - name: "SAP HA Prepare Pacemaker - azure_lb resource agent - Define load balancer port for health check when SAP HANA scale-up HA" ansible.builtin.set_fact: - __sap_ha_pacemaker_cluster_resource_lb_port: "626{{ sap_ha_pacemaker_cluster_hana_instance_number }}" + __sap_ha_pacemaker_cluster_resource_lb_port: "626{{ sap_ha_pacemaker_cluster_hana_instance_nr }}" when: "'hana_scaleup' in sap_ha_pacemaker_cluster_host_type[0]" # REPLACE with substring in any of the strings contained in the list - name: "SAP HA Prepare Pacemaker - azure_lb resource agent - Add resource: Azure Load Balancer (NLB L-4) for VIP routing when SAP HANA scale-up HA" ansible.builtin.set_fact: __sap_ha_pacemaker_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives + [__health_check] }}" - __sap_ha_pacemaker_cluster_vip_resource_id: "{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" vars: __health_check: - id: "hc_{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" + id: "hc_{{ vip_list_item.key }}" agent: "{{ __sap_ha_pacemaker_cluster_available_vip_agents[sap_ha_pacemaker_cluster_vip_method].agent }}" instance_attrs: - attrs: @@ -47,7 +47,7 @@ value: "{{ __sap_ha_pacemaker_cluster_register_socat_path.stdout }}" when: - __health_check.id is not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) - - ('hc_' ~ sap_ha_pacemaker_cluster_vip_resource_name ~ '_' ~ vip_list_item.key) not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) + - ('hc_' ~ vip_list_item.key) not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) - sap_ha_pacemaker_cluster_vip_method == 'azure_lb' - "'hana_scaleup' in sap_ha_pacemaker_cluster_host_type[0]" # REPLACE with substring in any of the strings contained in the list @@ -55,10 +55,9 @@ - name: "SAP HA Prepare Pacemaker - azure_lb resource agent - Add resource: Azure Load Balancer (NLB L-4) for VIP routing when SAP NetWeaver HA - ASCS and ERS" ansible.builtin.set_fact: __sap_ha_pacemaker_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives + [__health_check] }}" - __sap_ha_pacemaker_cluster_vip_resource_id: "{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" vars: __health_check: - id: "hc_{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" + id: "hc_{{ vip_list_item.key }}" agent: "{{ __sap_ha_pacemaker_cluster_available_vip_agents[sap_ha_pacemaker_cluster_vip_method].agent }}" instance_attrs: - attrs: @@ -66,13 +65,13 @@ value: "{{ lb_port_for_hc | default(0) }}" # Add default to ensure skip without errors - name: nc value: "{{ __sap_ha_pacemaker_cluster_register_socat_path.stdout }}" - loop: ["626{{ sap_ha_pacemaker_cluster_netweaver_abap_ascs_instance_number }}", "626{{ sap_ha_pacemaker_cluster_netweaver_abap_ers_instance_number }}"] + loop: ["626{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_instance_nr }}", "626{{ sap_ha_pacemaker_cluster_nwas_abap_ers_instance_nr }}"] loop_control: loop_var: lb_port_for_hc index_var: lb_port_for_hc_index label: "{{ lb_port_for_hc }}" when: - __health_check.id is not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) - - ('hc_' ~ sap_ha_pacemaker_cluster_vip_resource_name ~ '_' ~ vip_list_item.key) not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) + - ('hc_' ~ vip_list_item.key) not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) - sap_ha_pacemaker_cluster_vip_method == 'azure_lb' - "'nwas_abap_ascs_ers' in sap_ha_pacemaker_cluster_host_type[0]" # REPLACE with substring in any of the strings contained in the list diff --git a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_hyp_ibmpower_vm.yml b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_hyp_ibmpower_vm.yml index 306036c53..97b662d67 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_hyp_ibmpower_vm.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_hyp_ibmpower_vm.yml @@ -4,17 +4,18 @@ - name: "SAP HA Prepare Pacemaker - ipaddr resource agent - Add resource: OS network interface Virtual IP" ansible.builtin.set_fact: __sap_ha_pacemaker_cluster_resource_primitives: "{{ __sap_ha_pacemaker_cluster_resource_primitives + [__resource_vip] }}" - __sap_ha_pacemaker_cluster_vip_resource_id: "{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" vars: __resource_vip: - id: "{{ sap_ha_pacemaker_cluster_vip_resource_name }}_{{ vip_list_item.key }}" + id: "{{ vip_list_item.key }}" agent: "{{ __sap_ha_pacemaker_cluster_available_vip_agents['ipaddr'].agent }}" instance_attrs: - attrs: - name: ip value: "{{ vip_list_item.value }}" + - name: nic + value: "{{ sap_ha_pacemaker_cluster_vip_client_interface }}" when: - - sap_ha_pacemaker_cluster_vip_resource_name ~ '_' ~ vip_list_item.key not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) + - vip_list_item.key not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id')) - (sap_ha_pacemaker_cluster_vip_method == 'ipaddr') or (__sap_ha_pacemaker_cluster_available_vip_agents[sap_ha_pacemaker_cluster_vip_method].with is defined and 'ipaddr' in __sap_ha_pacemaker_cluster_available_vip_agents[sap_ha_pacemaker_cluster_vip_method].with) diff --git a/roles/sap_ha_pacemaker_cluster/tasks/platform/include_vars_platform.yml b/roles/sap_ha_pacemaker_cluster/tasks/platform/include_vars_platform.yml index 6a1ad95f8..2779d9d65 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/platform/include_vars_platform.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/platform/include_vars_platform.yml @@ -20,10 +20,10 @@ {% endfor %} when: __sap_ha_pacemaker_cluster_platform == "cloud_aws_ec2_vs" - - name: "SAP HA Prepare Pacemaker - IBM Power VS from IBM Cloud - Set variable for fencing agent" ansible.builtin.set_fact: sap_ha_pacemaker_cluster_ibmcloud_powervs_host_guid: "{{ __sap_ha_pacemaker_cluster_register_ibmcloud_powervs_host }}" + sap_ha_pacemaker_cluster_ibmcloud_powervs_workspace_guid: '{{ __sap_ha_pacemaker_cluster_register_ibmcloud_powervs_workspace_crn | replace("::","") | regex_replace(".*\:") }}' when: __sap_ha_pacemaker_cluster_platform == "cloud_ibmcloud_powervs" # pcmk_host_map format: :;:... @@ -31,12 +31,30 @@ ansible.builtin.set_fact: __sap_ha_pacemaker_cluster_pcmk_host_map: |- {% for node in ansible_play_hosts_all -%} - {{ hostvars[node].ansible_hostname }}:{{ hostvars[node].sap_ha_pacemaker_cluster_ibmcloud_powervs_host_guid }} + {{ hostvars[node].ansible_hostname }}:{{ hostvars[node].sap_ha_pacemaker_cluster_ibmcloud_powervs_instance_id }} {%- if not loop.last %};{% endif %} {% endfor %} when: __sap_ha_pacemaker_cluster_platform == "cloud_ibmcloud_powervs" +- name: "SAP HA Prepare Pacemaker - IBM PowerVM - Set variable for fencing agent" + ansible.builtin.set_fact: + sap_ha_pacemaker_cluster_ibmpower_vm_hmc_system_partition_name: "{{ __sap_ha_pacemaker_cluster_register_ibmpower_vm_hmc_system_partition_name.stdout }}" + sap_ha_pacemaker_cluster_ibmpower_vm_hmc_system_host_mtms: "{{ __sap_ha_pacemaker_cluster_register_ibmpower_vm_hmc_system_host_mtms_gui_string.stdout }}" + + when: __sap_ha_pacemaker_cluster_platform == "hyp_ibmpower_vm" + +# pcmk_host_map format: :;:... +- name: "SAP HA Prepare Pacemaker - IBM PowerVM - Assemble host mapping" + ansible.builtin.set_fact: + __sap_ha_pacemaker_cluster_pcmk_host_map: |- + {% for node in ansible_play_hosts_all -%} + {{ hostvars[node].ansible_hostname }}:{{ hostvars[node].sap_ha_pacemaker_cluster_ibmpower_vm_hmc_system_partition_name }} + {%- if not loop.last %};{% endif %} + {% endfor %} + when: __sap_ha_pacemaker_cluster_platform == "hyp_ibmpower_vm" + + # pcmk_host_map format: :;:... - name: "SAP HA Prepare Pacemaker - IBM Cloud VS - Assemble host mapping" ansible.builtin.set_fact: diff --git a/roles/sap_ha_pacemaker_cluster/tasks/platform/register_sysinfo_cloud_ibmcloud_powervs.yml b/roles/sap_ha_pacemaker_cluster/tasks/platform/register_sysinfo_cloud_ibmcloud_powervs.yml index c31078c72..63be853f6 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/platform/register_sysinfo_cloud_ibmcloud_powervs.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/platform/register_sysinfo_cloud_ibmcloud_powervs.yml @@ -1,9 +1,11 @@ --- # Ansible facts rely on SMBIOS/DMI, which does not exist on ppc64le CPU Architecture. -# Identify from RSCT binary instead. -- name: "SAP HA Prepare Pacemaker - IBM Power VS from IBM Cloud - Register instance ID" + +# alt command using IBM Power RSCT binary: /opt/rsct/bin/ctgethscid | grep PartitionUUID | cut -d \" -f2 +# alt command using cloud-init data: cat /run/cloud-init/instance-data.json | grep uuid | cut -d \" -f4 +- name: SAP HA Prepare Pacemaker - IBM Power VS from IBM Cloud - IBM Power Virtual Server instance ID ansible.builtin.shell: | - /opt/rsct/bin/ctgethscid -value PartitionUUID - register: __sap_ha_pacemaker_cluster_register_ibmcloud_powervs_host + set -o pipefail && echo $(tr -d '\0' < /proc/device-tree/ibm,partition-name) + register: __sap_ha_pacemaker_cluster_register_ibmcloud_powervs_workspace_guid changed_when: false check_mode: false diff --git a/roles/sap_ha_pacemaker_cluster/tasks/platform/register_sysinfo_hyp_ibmpower_vm.yml b/roles/sap_ha_pacemaker_cluster/tasks/platform/register_sysinfo_hyp_ibmpower_vm.yml new file mode 100644 index 000000000..f703571ec --- /dev/null +++ b/roles/sap_ha_pacemaker_cluster/tasks/platform/register_sysinfo_hyp_ibmpower_vm.yml @@ -0,0 +1,32 @@ +--- +# Ansible facts rely on SMBIOS/DMI, which does not exist on ppc64le CPU Architecture. +# Use Open Firmware (OF) device tree values + +# Do not use cat on /proc files to avoid error 'ignored null byte in input' + + +# The System's Machine Type and Machine Serial Number (MTMS) is a combined string, which is sometimes separated by underscore '_' +# and in IBM Power HMC Web GUI is separated by asterisk '*' +# An example of the combined string is '9009-22A' as Machine Type + '*' + '11A111' as Machine Serial Number +# This is an alternative value to populate --managed instead of the IBM PowerVM HMC System Name, +# which works with the command 'lssyscfg -r lpar -m <<--managed value of HMC System Name or System MTMS or System UUID>> +- name: SAP HA Prepare Pacemaker - IBM Power VM - HMC System (aka. Hypervisor Node) Machine Type and Machine Serial Number (MTMS) + ansible.builtin.shell: | + set -o pipefail && echo $(tr -d '\0' < /proc/device-tree/model | sed 's/IBM,//g')*$(tr -d '\0' < /proc/device-tree/ibm,hardware-sn) + register: __sap_ha_pacemaker_cluster_register_ibmpower_vm_hmc_system_host_mtms_gui_string + changed_when: false + check_mode: false + +- name: SAP HA Prepare Pacemaker - IBM Power VM - HMC System's Partition Name of the Virtual Machine + ansible.builtin.shell: | + set -o pipefail && echo $(tr -d '\0' < /proc/device-tree/ibm,partition-name) + register: __sap_ha_pacemaker_cluster_register_ibmpower_vm_hmc_system_partition_name + changed_when: false + check_mode: false + +- name: SAP HA Prepare Pacemaker - IBM Power VM - HMC System's Partition UUID of the Virtual Machine + ansible.builtin.shell: | + set -o pipefail && echo $(tr -d '\0' < /proc/device-tree/ibm,partition-uuid) + register: __sap_ha_pacemaker_cluster_register_ibmpower_vm_hmc_system_partition_uuid + changed_when: false + check_mode: false diff --git a/roles/sap_ha_pacemaker_cluster/tasks/validate_input_parameters.yml b/roles/sap_ha_pacemaker_cluster/tasks/validate_input_parameters.yml index 2ae0ed659..ad8831114 100644 --- a/roles/sap_ha_pacemaker_cluster/tasks/validate_input_parameters.yml +++ b/roles/sap_ha_pacemaker_cluster/tasks/validate_input_parameters.yml @@ -1,30 +1,145 @@ --- # The SAP ID must follow a strict format and not use reserved special values -# TODO: This check may be better placed in a SAP role earlier in the chain... -- name: "SAP HA Prepare Pacemaker - Validate SAP System ID (SAP HANA)" +- name: "SAP HA Prepare Pacemaker - (SAP HANA) Validate SAP System ID" ansible.builtin.assert: that: - sap_ha_pacemaker_cluster_hana_sid | length == 3 - sap_ha_pacemaker_cluster_hana_sid not in __sap_sid_prohibited + fail_msg: | + Host type = {{ sap_ha_pacemaker_cluster_host_type }} + Requires 'sap_ha_pacemaker_cluster_hana_sid' to be defined! when: - - "'hana' in sap_ha_pacemaker_cluster_host_type" - - sap_ha_pacemaker_cluster_hana_sid is defined - - sap_ha_pacemaker_cluster_hana_sid | length > 0 + - sap_ha_pacemaker_cluster_host_type | select('search', 'hana') | length > 0 -- name: "SAP HA Prepare Pacemaker - Validate SAP System ID (SAP Netweaver)" +- name: "SAP HA Prepare Pacemaker - (SAP HANA) Validate SAP Instance Number" ansible.builtin.assert: that: - - sap_ha_pacemaker_cluster_netweaver_sid | length == 3 - - sap_ha_pacemaker_cluster_netweaver_sid not in __sap_sid_prohibited + - ( + sap_ha_pacemaker_cluster_hana_instance_nr | type_debug != 'int' + and sap_ha_pacemaker_cluster_hana_instance_nr | length == 2 + ) + or + ( + sap_ha_pacemaker_cluster_hana_instance_nr | type_debug == 'int' + and sap_ha_pacemaker_cluster_hana_instance_nr is regex("^[0-9][0-9]$") + ) + fail_msg: | + + Host type = {{ sap_ha_pacemaker_cluster_host_type }} + Requires 'sap_ha_pacemaker_cluster_hana_instance_nr' to be defined. + + The instance number must be exactly 2 digits. + Add quotes if the number starts with a 0! when: - - "'nwas' in sap_ha_pacemaker_cluster_host_type" - - sap_ha_pacemaker_cluster_netweaver_sid is defined - - sap_ha_pacemaker_cluster_netweaver_sid | length > 0 + - sap_ha_pacemaker_cluster_host_type | select('search', 'hana') | length > 0 -- name: "SAP HA Prepare Pacemaker - Verify that a SID is defined" +- name: "SAP HA Prepare Pacemaker - (SAP NetWeaver) Validate SAP System ID" ansible.builtin.assert: that: - - sap_ha_pacemaker_cluster_hana_sid is defined - or sap_ha_pacemaker_cluster_netweaver_sid is defined - - sap_ha_pacemaker_cluster_hana_sid | length > 0 - or sap_ha_pacemaker_cluster_netweaver_sid | length > 0 + - sap_ha_pacemaker_cluster_nwas_abap_sid | length == 3 + - sap_ha_pacemaker_cluster_nwas_abap_sid not in __sap_sid_prohibited + fail_msg: | + Host type = {{ sap_ha_pacemaker_cluster_host_type }} + Requires 'sap_ha_pacemaker_cluster_nwas_abap_sid' to be defined! + when: + - sap_ha_pacemaker_cluster_host_type | select('search', 'nwas') | length > 0 + +- name: "SAP HA Prepare Pacemaker - (SAP NetWeaver) Validate SAP Instance Number" + when: + - sap_ha_pacemaker_cluster_host_type | select('search', 'nwas_abap') | length > 0 + ansible.builtin.assert: + that: + - ( + ascs_ers_nr_item | type_debug != 'int' + and ascs_ers_nr_item | length == 2 + ) + or + ( + ascs_ers_nr_item | type_debug == 'int' + and ascs_ers_nr_item is regex("^[0-9][0-9]$") + ) + fail_msg: | + + Host type = {{ sap_ha_pacemaker_cluster_host_type }} + Requires the ASCS/ERS instance numbers to be defined: + - sap_ha_pacemaker_cluster_nwas_abap_ascs_instance_nr + - sap_ha_pacemaker_cluster_nwas_abap_ers_instance_nr + + The instance number must be exactly 2 digits. + Add quotes if the number starts with a 0! + + loop: + - "{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_instance_nr }}" + - "{{ sap_ha_pacemaker_cluster_nwas_abap_ers_instance_nr }}" + loop_control: + loop_var: ascs_ers_nr_item + + +# NIC definition validation +- name: "SAP HA Prepare Pacemaker - Verify that a custom NIC name is defined when multiple NICs exist" + ansible.builtin.assert: + that: + - sap_ha_pacemaker_cluster_vip_client_interface is defined + - sap_ha_pacemaker_cluster_vip_client_interface | length > 0 + fail_msg: + Multiple interfaces are found on the system. + + {{ ansible_interfaces | to_nice_yaml }} + + In this case 'sap_ha_pacemaker_cluster_vip_client_interface' must be defined. + when: + - ansible_interfaces | length > 2 + +- name: "SAP HA Prepare Pacemaker - Verify that the custom NIC name exists" + ansible.builtin.assert: + that: + - sap_ha_pacemaker_cluster_vip_client_interface in ansible_interfaces + fail_msg: "The interface '{{ sap_ha_pacemaker_cluster_vip_client_interface }}' does not exist on this system!" + when: + - sap_ha_pacemaker_cluster_vip_client_interface | length > 0 + +# VIP definition validation +- name: "SAP HA Prepare Pacemaker - (HANA primary) Verify that the VIP is defined" + ansible.builtin.assert: + that: + - sap_ha_pacemaker_cluster_vip_hana_primary_ip_address is defined + - sap_ha_pacemaker_cluster_vip_hana_primary_ip_address | length > 0 + fail_msg: "Host type = '{{ sap_ha_pacemaker_cluster_host_type }}', but 'sap_ha_pacemaker_cluster_vip_hana_primary_ip_address' is not defined." + when: + - sap_ha_pacemaker_cluster_host_type | select('search', 'hana') | length > 0 + +- name: "SAP HA Prepare Pacemaker - (NetWeaver ASCS) Verify that the VIP is defined" + ansible.builtin.assert: + that: + - sap_ha_pacemaker_cluster_vip_nwas_abap_ascs_ip_address is defined + - sap_ha_pacemaker_cluster_vip_nwas_abap_ascs_ip_address | length > 0 + fail_msg: "Host type = '{{ sap_ha_pacemaker_cluster_host_type }}', but 'sap_ha_pacemaker_cluster_vip_nwas_abap_ascs_ip_address' is not defined." + when: + - sap_ha_pacemaker_cluster_host_type | select('search', 'nwas_abap_ascs') | length > 0 + +- name: "SAP HA Prepare Pacemaker - (NetWeaver ERS) Verify that the VIP is defined" + ansible.builtin.assert: + that: + - sap_ha_pacemaker_cluster_vip_nwas_abap_ers_ip_address is defined + - sap_ha_pacemaker_cluster_vip_nwas_abap_ers_ip_address | length > 0 + fail_msg: "Host type = '{{ sap_ha_pacemaker_cluster_host_type }}', but 'sap_ha_pacemaker_cluster_vip_nwas_abap_ers_ip_address' is not defined." + when: + - sap_ha_pacemaker_cluster_host_type | select('search', 'nwas_abap_ascs_ers') | length > 0 + +- name: "SAP HA Prepare Pacemaker - (NetWeaver PAS) Verify that the VIP is defined" + ansible.builtin.assert: + that: + - sap_ha_pacemaker_cluster_vip_nwas_abap_pas_ip_address is defined + - sap_ha_pacemaker_cluster_vip_nwas_abap_pas_ip_address | length > 0 + fail_msg: "Host type = '{{ sap_ha_pacemaker_cluster_host_type }}', but 'sap_ha_pacemaker_cluster_vip_nwas_abap_pas_ip_address' is not defined." + when: + - sap_ha_pacemaker_cluster_host_type | select('search', 'nwas_abap_pas') | length > 0 + +- name: "SAP HA Prepare Pacemaker - (NetWeaver AAS) Verify that the ERS VIP is defined" + ansible.builtin.assert: + that: + - sap_ha_pacemaker_cluster_vip_nwas_abap_aas_ip_address is defined + - sap_ha_pacemaker_cluster_vip_nwas_abap_aas_ip_address | length > 0 + fail_msg: "Host type = '{{ sap_ha_pacemaker_cluster_host_type }}', but 'sap_ha_pacemaker_cluster_vip_nwas_abap_aas_ip_address' is not defined." + when: + - sap_ha_pacemaker_cluster_host_type | select('search', 'nwas_abap_pas_aas') | length > 0 diff --git a/roles/sap_ha_pacemaker_cluster/templates/cluster_create_config.j2 b/roles/sap_ha_pacemaker_cluster/templates/cluster_create_config.j2 index 5f35649d0..87a96a067 100644 --- a/roles/sap_ha_pacemaker_cluster/templates/cluster_create_config.j2 +++ b/roles/sap_ha_pacemaker_cluster/templates/cluster_create_config.j2 @@ -5,66 +5,46 @@ # Created by: {{ ansible_role_name }} # The name of the cluster -ha_cluster_cluster_name: {{ __sap_ha_pacemaker_cluster_cluster_name }} +ha_cluster_cluster_name: {{ ha_cluster_cluster_name | default('') }} -{% if __sap_ha_pacemaker_cluster_cluster_properties is defined and __sap_ha_pacemaker_cluster_cluster_properties|length > 0 %} # Properties that enable and control cluster behavior ha_cluster_cluster_properties: -{{ __sap_ha_pacemaker_cluster_cluster_properties | to_nice_yaml(indent=2) }} -{%- endif %} +{{ ha_cluster_cluster_properties | default() | to_nice_yaml(indent=2) }} -{% if __sap_ha_pacemaker_cluster_constraints_colocation is defined and __sap_ha_pacemaker_cluster_constraints_colocation|length > 0 %} # Definition of resources which depend on other resources ha_cluster_constraints_colocation: -{{ __sap_ha_pacemaker_cluster_constraints_colocation | to_nice_yaml(indent=2) }} -{%- endif -%} +{{ ha_cluster_constraints_colocation | default() | to_nice_yaml(indent=2) }} -{% if __sap_ha_pacemaker_cluster_constraints_location is defined and __sap_ha_pacemaker_cluster_constraints_location|length > 0 %} # Definition of resources which have specific location dependencies or preferences ha_cluster_constraints_location: -{{ __sap_ha_pacemaker_cluster_constraints_location | to_nice_yaml(indent=2) }} -{%- endif %} +{{ ha_cluster_constraints_location | default() | to_nice_yaml(indent=2) }} -{% if __sap_ha_pacemaker_cluster_constraints_order is defined and __sap_ha_pacemaker_cluster_constraints_order|length > 0 %} # Definition of an order in which resources must be started. # They are automatically stopped in reverse order. ha_cluster_constraints_order: -{{ __sap_ha_pacemaker_cluster_constraints_order | to_nice_yaml(indent=2) }} -{%- endif %} +{{ ha_cluster_constraints_order | default() | to_nice_yaml(indent=2) }} -{% if __sap_ha_pacemaker_cluster_extra_packages is defined and __sap_ha_pacemaker_cluster_extra_packages|length > 0 %} # Extra packages that are needed for this HA environment ha_cluster_extra_packages: -{{ __sap_ha_pacemaker_cluster_extra_packages | to_nice_yaml(indent=2) }} -{%- endif %} +{{ ha_cluster_extra_packages | default() | to_nice_yaml(indent=2) }} -{% if __sap_ha_pacemaker_cluster_fence_agent_packages is defined and __sap_ha_pacemaker_cluster_fence_agent_packages|length > 0 %} # Fence agent package(s) for this HA environment ha_cluster_fence_agent_packages: -{{ __sap_ha_pacemaker_cluster_fence_agent_packages | to_nice_yaml(indent=2) }} -{%- endif %} +{{ ha_cluster_fence_agent_packages | default() | to_nice_yaml(indent=2) }} -{% if __sap_ha_pacemaker_cluster_repos is defined and __sap_ha_pacemaker_cluster_repos|length > 0 %} # Definition of repositories to enable (if disable) to ensure # access to all required packages __ha_cluster_repos: -{{ __sap_ha_pacemaker_cluster_repos | to_nice_yaml(indent=2) }} -{%- endif %} +{{ __ha_cluster_repos | default() | to_nice_yaml(indent=2) }} -{% if __sap_ha_pacemaker_cluster_resource_clones is defined and __sap_ha_pacemaker_cluster_resource_clones|length > 0 %} # Definition of resources that are cloned and monitored on all nodes ha_cluster_resource_clones: -{{ __sap_ha_pacemaker_cluster_resource_clones | to_nice_yaml(indent=2) }} -{%- endif %} +{{ ha_cluster_resource_clones | default() | to_nice_yaml(indent=2) }} -{% if __sap_ha_pacemaker_cluster_resource_groups is defined and __sap_ha_pacemaker_cluster_resource_groups|length > 0 %} # Definition of resources that are grouped together ha_cluster_resource_groups: -{{ __sap_ha_pacemaker_cluster_resource_groups | to_nice_yaml(indent=2) }} -{%- endif %} +{{ ha_cluster_resource_groups | default() | to_nice_yaml(indent=2) }} -{% if __sap_ha_pacemaker_cluster_resource_primitives is defined and __sap_ha_pacemaker_cluster_resource_primitives|length > 0 %} # Definition of all cluster resources ha_cluster_resource_primitives: -{{ __sap_ha_pacemaker_cluster_resource_primitives | to_nice_yaml(indent=2) }} -{%- endif %} +{{ ha_cluster_resource_primitives | default()| to_nice_yaml(indent=2) }} diff --git a/roles/sap_ha_pacemaker_cluster/vars/hana_scaleout_common.yml b/roles/sap_ha_pacemaker_cluster/vars/hana_scaleout_common.yml index 4e356cae9..4175257b5 100644 --- a/roles/sap_ha_pacemaker_cluster/vars/hana_scaleout_common.yml +++ b/roles/sap_ha_pacemaker_cluster/vars/hana_scaleout_common.yml @@ -3,7 +3,7 @@ # # TODO: make sure to first respect 'ha_cluster' native variables -sap_ha_pacemaker_cluster_sap_extra_packages: +__sap_ha_pacemaker_cluster_sap_extra_packages: - resource-agents-sap-hana-scaleout sap_ha_pacemaker_cluster_ra_hana: SAPHanaController diff --git a/roles/sap_ha_pacemaker_cluster/vars/hana_scaleup_common.yml b/roles/sap_ha_pacemaker_cluster/vars/hana_scaleup_common.yml index 5c76b2497..85043b5c5 100644 --- a/roles/sap_ha_pacemaker_cluster/vars/hana_scaleup_common.yml +++ b/roles/sap_ha_pacemaker_cluster/vars/hana_scaleup_common.yml @@ -3,7 +3,7 @@ # # TODO: make sure to first respect 'ha_cluster' native variables -sap_ha_pacemaker_cluster_sap_extra_packages: +__sap_ha_pacemaker_cluster_sap_extra_packages: - resource-agents-sap-hana sap_ha_pacemaker_cluster_ra_hana: SAPHana diff --git a/roles/sap_ha_pacemaker_cluster/vars/main.yml b/roles/sap_ha_pacemaker_cluster/vars/main.yml index c96a08fbf..e0dbd3eb6 100644 --- a/roles/sap_ha_pacemaker_cluster/vars/main.yml +++ b/roles/sap_ha_pacemaker_cluster/vars/main.yml @@ -27,42 +27,17 @@ __sap_ha_pacemaker_cluster_required_facts: # - virtualization_role # subset: virtual # - virtualization_type # subset: virtual -# Define empty parameters to avoid undefined input variables. -# The arguments_spec check complains. -# The actual values must be empty, they are set by various tasks! +# By default assume non-multi-NIC configuration. +# This is automatically adjusted during preparation tasks. +__sap_ha_pacemaker_cluster_nic_multi_bool: false -__sap_ha_pacemaker_cluster_hana_primary_synonyms: - - primary - - hana_primary - - promoted - - rw - -__sap_ha_pacemaker_cluster_hana_secondary_synonyms: - - secondary - - hana_secondary - - unpromoted - - ro - -__sap_ha_pacemaker_cluster_nwas_ascs_synonyms: - - ascs - - nwas_ascs - - nwas_abap_ascs - -__sap_ha_pacemaker_cluster_nwas_ers_synonyms: - - ers - - nwas_ers - - nwas_abap_ers - -__sap_ha_pacemaker_cluster_nwas_pas_synonyms: - - pas - - nwas_pas - - nwas_abap_pas +# By default use the construction of IPaddr2 VIP resources. +# Platforms define different methods as applicable. +sap_ha_pacemaker_cluster_vip_method: ipaddr # (cloud) platform helper variable - leave empty for default = not cloud __sap_ha_pacemaker_cluster_platform: '' -__sap_ha_pacemaker_cluster_supported_platforms: - - cloud_aws_ec2_vs - - cloud_msazure_vm + # ATTENTION: # Any variables for 'ha_cluster' which this SAP role supports/inherits should also @@ -71,14 +46,26 @@ __sap_ha_pacemaker_cluster_supported_platforms: # - conditionals (if applicable) # - config report template # -__sap_ha_pacemaker_cluster_cluster_name: '' +# TODO: verify that the task flow logic works without these explicit +# pre-definitions. Otherwise there is a need to hard-code parameters +# which have defaults in the 'ha_cluster' LSR. +# Remove this section when validated. +# +# Never set defaults for these: +#__sap_ha_pacemaker_cluster_cluster_name: +#__sap_ha_pacemaker_cluster_hacluster_user_password: + + +# Pre-define internal optional parameters to avoid defaults in the code: +__sap_ha_pacemaker_cluster_sap_extra_packages: [] +__sap_ha_pacemaker_cluster_platform_extra_packages: [] + __sap_ha_pacemaker_cluster_cluster_properties: [] __sap_ha_pacemaker_cluster_constraints_colocation: [] __sap_ha_pacemaker_cluster_constraints_location: [] __sap_ha_pacemaker_cluster_constraints_order: [] __sap_ha_pacemaker_cluster_extra_packages: [] __sap_ha_pacemaker_cluster_fence_agent_packages: [] -__sap_ha_pacemaker_cluster_hacluster_password: __sap_ha_pacemaker_cluster_repos: [] __sap_ha_pacemaker_cluster_resource_primitives: [] __sap_ha_pacemaker_cluster_resource_groups: [] diff --git a/roles/sap_ha_pacemaker_cluster/vars/nwas_abap_ascs_ers.yml b/roles/sap_ha_pacemaker_cluster/vars/nwas_abap_ascs_ers.yml index a4118f6f7..2daf0d2b5 100644 --- a/roles/sap_ha_pacemaker_cluster/vars/nwas_abap_ascs_ers.yml +++ b/roles/sap_ha_pacemaker_cluster/vars/nwas_abap_ascs_ers.yml @@ -1,2 +1,15 @@ --- -sap_ha_pacemaker_cluster_vip_resource_name: "vip_{{ sap_ha_pacemaker_cluster_netweaver_sid }}_{{ sap_ha_pacemaker_cluster_netweaver_instance_number }}" +#sap_ha_pacemaker_cluster_vip_resource_name: "vip_{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}" + +# The following directories are appended to the 'nfs_path' of the '/usr/sap' storage +# definition. +# Therefore, the /usr/sap prefix must be left out of the listed path items. +__sap_ha_pacemaker_cluster_nwas_abap_ascs_ers_filesystems: + - "{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}/ASCS{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_instance_nr }}" + - "{{ sap_ha_pacemaker_cluster_nwas_abap_sid }}/ERS{{ sap_ha_pacemaker_cluster_nwas_abap_ers_instance_nr }}" + +# List of ASCS/ERS profile names. +# Used in tasks/configure_nwas_postinstallation.yml for sap_cluster_connector setup. +__sap_ha_pacemaker_cluster_nwas_abap_ascs_ers_profile_paths: + - "{{ sap_ha_pacemaker_cluster_nwas_abap_ascs_sapinstance_start_profile_string }}" + - "{{ sap_ha_pacemaker_cluster_nwas_abap_ers_sapinstance_start_profile_string }}" diff --git a/roles/sap_ha_pacemaker_cluster/vars/nwas_common.yml b/roles/sap_ha_pacemaker_cluster/vars/nwas_common.yml index 21dd17d20..c74b238e6 100644 --- a/roles/sap_ha_pacemaker_cluster/vars/nwas_common.yml +++ b/roles/sap_ha_pacemaker_cluster/vars/nwas_common.yml @@ -3,5 +3,6 @@ # # TODO: make sure to first respect 'ha_cluster' native variables -sap_ha_pacemaker_cluster_sap_extra_packages: +__sap_ha_pacemaker_cluster_sap_extra_packages: - resource-agents-sap + - "{% if sap_ha_pacemaker_cluster_enable_cluster_connector %}{{ __sap_ha_pacemaker_cluster_halib_package }}{% endif %}" diff --git a/roles/sap_ha_pacemaker_cluster/vars/platform_cloud_aws_ec2_vs.yml b/roles/sap_ha_pacemaker_cluster/vars/platform_cloud_aws_ec2_vs.yml index e4b555b9b..238960267 100644 --- a/roles/sap_ha_pacemaker_cluster/vars/platform_cloud_aws_ec2_vs.yml +++ b/roles/sap_ha_pacemaker_cluster/vars/platform_cloud_aws_ec2_vs.yml @@ -6,7 +6,7 @@ sap_ha_pacemaker_cluster_fence_agent_packages: - fence-agents-aws -sap_ha_pacemaker_cluster_platform_extra_packages: +__sap_ha_pacemaker_cluster_platform_extra_packages: - awscli __sap_ha_pacemaker_cluster_repos: @@ -18,7 +18,7 @@ __sap_ha_pacemaker_cluster_aws_instances: [] # When aws credentials and region are not defined it will # default to using the aws cli configuration. -# aws cli is configured by default for the VIP resource. +# The aws cli is currently configured anyway for the standard AWS VIP resource. sap_ha_pacemaker_cluster_stonith_default: id: "res_fence_aws" agent: "stonith:fence_aws" diff --git a/roles/sap_ha_pacemaker_cluster/vars/platform_cloud_gcp_ce_vm.yml b/roles/sap_ha_pacemaker_cluster/vars/platform_cloud_gcp_ce_vm.yml index 160f6135d..34e9ade20 100644 --- a/roles/sap_ha_pacemaker_cluster/vars/platform_cloud_gcp_ce_vm.yml +++ b/roles/sap_ha_pacemaker_cluster/vars/platform_cloud_gcp_ce_vm.yml @@ -6,7 +6,7 @@ sap_ha_pacemaker_cluster_fence_agent_packages: - fence-agents-gce -sap_ha_pacemaker_cluster_platform_extra_packages: +__sap_ha_pacemaker_cluster_platform_extra_packages: - resource-agents-gcp __sap_ha_pacemaker_cluster_repos: diff --git a/roles/sap_ha_pacemaker_cluster/vars/platform_cloud_ibmcloud_powervs.yml b/roles/sap_ha_pacemaker_cluster/vars/platform_cloud_ibmcloud_powervs.yml index af35b0202..82e71e1c9 100644 --- a/roles/sap_ha_pacemaker_cluster/vars/platform_cloud_ibmcloud_powervs.yml +++ b/roles/sap_ha_pacemaker_cluster/vars/platform_cloud_ibmcloud_powervs.yml @@ -6,7 +6,7 @@ sap_ha_pacemaker_cluster_fence_agent_packages: - fence-agents-ibm-powervs -#sap_ha_pacemaker_cluster_platform_extra_packages: +#__sap_ha_pacemaker_cluster_platform_extra_packages: # - __sap_ha_pacemaker_cluster_repos: @@ -28,10 +28,10 @@ sap_ha_pacemaker_cluster_stonith_default: token: "{{ sap_ha_pacemaker_cluster_ibmcloud_api_key }}" region: "{{ sap_ha_pacemaker_cluster_ibmcloud_region }}" crn: "{{ sap_ha_pacemaker_cluster_ibmcloud_powervs_workspace_crn }}" - instance: "{{ sap_ha_pacemaker_cluster_ibmcloud_powervs_workspace_guid }}" - plug: "{{ sap_ha_pacemaker_cluster_ibmcloud_powervs_host_guid }}" # Identified during execution initial tasks, populated when variables are imported - api-type: "{{ sap_ha_pacemaker_cluster_ibmcloud_powervs_api_type | default('private') }}" - proxy: "{{ sap_ha_pacemaker_cluster_ibmcloud_powervs_forward_proxy_url }}" + instance: "{{ sap_ha_pacemaker_cluster_ibmcloud_powervs_workspace_guid }}" # Identified during execution initial tasks, populated when variables are imported + plug: "{{ sap_ha_pacemaker_cluster_ibmcloud_powervs_instance_id }}" # Identified during execution initial tasks, populated when variables are imported + api-type: "{{ sap_ha_pacemaker_cluster_ibmcloud_powervs_api_type | default('public') }}" # Dependent on network interface attachments, if no public network interface then 'private' value must be provided. + proxy: "{{ sap_ha_pacemaker_cluster_ibmcloud_powervs_forward_proxy_url | default('') }}" # Dependent on network interface attachments, if no public network interface then a valid HTTP Proxy URL value must be provided. sap_ha_pacemaker_cluster_fence_options: pcmk_reboot_retries: 4 diff --git a/roles/sap_ha_pacemaker_cluster/vars/platform_cloud_ibmcloud_vs.yml b/roles/sap_ha_pacemaker_cluster/vars/platform_cloud_ibmcloud_vs.yml index 5430a4608..076495c61 100644 --- a/roles/sap_ha_pacemaker_cluster/vars/platform_cloud_ibmcloud_vs.yml +++ b/roles/sap_ha_pacemaker_cluster/vars/platform_cloud_ibmcloud_vs.yml @@ -6,7 +6,7 @@ sap_ha_pacemaker_cluster_fence_agent_packages: - fence-agents-ibm-vpc -#sap_ha_pacemaker_cluster_platform_extra_packages: +#__sap_ha_pacemaker_cluster_platform_extra_packages: # - __sap_ha_pacemaker_cluster_repos: diff --git a/roles/sap_ha_pacemaker_cluster/vars/platform_cloud_msazure_vm.yml b/roles/sap_ha_pacemaker_cluster/vars/platform_cloud_msazure_vm.yml index 2d056bf12..cf23a19a2 100644 --- a/roles/sap_ha_pacemaker_cluster/vars/platform_cloud_msazure_vm.yml +++ b/roles/sap_ha_pacemaker_cluster/vars/platform_cloud_msazure_vm.yml @@ -6,7 +6,7 @@ sap_ha_pacemaker_cluster_fence_agent_packages: - fence-agents-azure-arm -sap_ha_pacemaker_cluster_platform_extra_packages: +__sap_ha_pacemaker_cluster_platform_extra_packages: - socat __sap_ha_pacemaker_cluster_repos: diff --git a/roles/sap_ha_pacemaker_cluster/vars/platform_hyp_ibmpower_vm.yml b/roles/sap_ha_pacemaker_cluster/vars/platform_hyp_ibmpower_vm.yml index 806d5eb42..083622f47 100644 --- a/roles/sap_ha_pacemaker_cluster/vars/platform_hyp_ibmpower_vm.yml +++ b/roles/sap_ha_pacemaker_cluster/vars/platform_hyp_ibmpower_vm.yml @@ -6,7 +6,7 @@ sap_ha_pacemaker_cluster_fence_agent_packages: - fence-agents-lpar -#sap_ha_pacemaker_cluster_platform_extra_packages: +#__sap_ha_pacemaker_cluster_platform_extra_packages: # - __sap_ha_pacemaker_cluster_repos: @@ -25,13 +25,13 @@ sap_ha_pacemaker_cluster_stonith_default: id: "res_fence_lpar" agent: "stonith:fence_lpar" options: - ipaddr: "{{ sap_ha_pacemaker_cluster_ibmpower_vm_hmc_host }}" + ip: "{{ sap_ha_pacemaker_cluster_ibmpower_vm_hmc_host }}" ipport: "{{ sap_ha_pacemaker_cluster_ibmpower_vm_hmc_host_port }}" - login: "{{ sap_ha_pacemaker_cluster_ibmpower_vm_hmc_host_login }}" + username: "{{ sap_ha_pacemaker_cluster_ibmpower_vm_hmc_host_login }}" password: "{{ sap_ha_pacemaker_cluster_ibmpower_vm_hmc_host_login_password }}" hmc_version: "{{ sap_ha_pacemaker_cluster_ibmpower_vm_hmc_host_version | default('4') }}" - plug: "{{ sap_ha_pacemaker_cluster_ibmpower_vm_uuid }}" - + managed: "{{ sap_ha_pacemaker_cluster_ibmpower_vm_hmc_system_host_mtms }}" # Identified during execution initial tasks, populated when variables are imported + #plug: "{{ sap_ha_pacemaker_cluster_ibmpower_vm_hmc_system_partition_name }}" # Unnecessary when using pcmk_host_map. Identified during execution initial tasks, populated when variables are imported sap_ha_pacemaker_cluster_fence_options: pcmk_reboot_retries: 4 diff --git a/roles/sap_ha_pacemaker_cluster/vars/redhat.yml b/roles/sap_ha_pacemaker_cluster/vars/redhat.yml index a65619099..dcf8452bc 100644 --- a/roles/sap_ha_pacemaker_cluster/vars/redhat.yml +++ b/roles/sap_ha_pacemaker_cluster/vars/redhat.yml @@ -4,3 +4,18 @@ __sap_ha_pacemaker_cluster_repos: - id: "rhel-{{ ansible_distribution_major_version }}-for-{{ ansible_architecture }}-highavailability-e4s-rpms" name: High Availability + +__sap_ha_pacemaker_cluster_halib_package: sap-cluster-connector + +# List of configuration lines that must be added to the instance profiles. +# Used in tasks/configure_nwas_ascs_ers_postinstallation.yml for SAP HA Interface setup. +__sap_ha_pacemaker_cluster_connector_config_lines: + - "service/halib = $(DIR_EXECUTABLE)/saphascriptco.so" + - "service/halib_cluster_connector = /usr/bin/sap_cluster_connector" + +# Cluster command to manage resources - pcs commands in Redhat OS family. +__sap_ha_pacemaker_cluster_command: + resource_stop: "pcs resource disable" + resource_start: "pcs resource enable" + resource_defaults_show: "pcs resource defaults config" + resource_defaults_update: "pcs resource defaults update" diff --git a/roles/sap_ha_pacemaker_cluster/vars/suse.yml b/roles/sap_ha_pacemaker_cluster/vars/suse.yml new file mode 100644 index 000000000..c821de804 --- /dev/null +++ b/roles/sap_ha_pacemaker_cluster/vars/suse.yml @@ -0,0 +1,15 @@ +--- +__sap_ha_pacemaker_cluster_halib_package: sap-suse-cluster-connector + +# List of configuration lines that must be added to the instance profiles. +# Used in tasks/configure_nwas_ascs_ers_postinstallation.yml for SAP HA Interface setup. +__sap_ha_pacemaker_cluster_connector_config_lines: + - "service/halib = $(DIR_EXECUTABLE)/saphascriptco.so" + - "service/halib_cluster_connector = /usr/bin/sap_suse_cluster_connector" + +# Cluster commands to manage resources - crmsh commands in SUSE OS family. +__sap_ha_pacemaker_cluster_command: + resource_stop: "crm resource stop" + resource_start: "crm resource start" + resource_defaults_show: "crm configure show type:rsc_defaults" + resource_defaults_update: "crm configure rsc_defaults" diff --git a/roles/sap_hana_install/README.md b/roles/sap_hana_install/README.md index 3373a7dda..42ad2ca06 100644 --- a/roles/sap_hana_install/README.md +++ b/roles/sap_hana_install/README.md @@ -160,6 +160,12 @@ The firewall ports for SAP HANA are defined in member `port` of the first field member `state` is set to `enabled`, the ports will be enabled. If the member `state` is set to `disabled`, the ports will be disabled, which might be useful for testing. +Certain parameters have identical meanings, for supporting different naming schemes in playbooks and inventories. +You can find those in the task `Rename some variables used by hdblcm configfile` of the file `tasks/main.yml`. +Example: The parameter `sap_hana_install_number`, which is used by the role to define the hdblm parameter `number` +(= SAP HANA instance number) can be defined by setting `sap_hana_instance_number`, `sap_hana_install_instance_nr`, +`sap_hana_install_instance_number`, or `sap_hana_install_number`. The order of precedence is from left to right. + ### Default Parameters Please check the default parameters file for more information on other parameters that can be used as an input @@ -189,7 +195,7 @@ Sample Ansible Playbook Execution sap_hana_install_software_directory: /software/hana sap_hana_install_common_master_password: 'NewPass$321' sap_hana_install_sid: 'H01' - sap_hana_install_instance_number: '00' + sap_hana_install_instance_nr: '00' roles: - sap_hana_install ``` @@ -208,7 +214,7 @@ Sample Ansible Playbook Execution sap_hana_install_root_password: 'NewPass$321' sap_hana_install_addhosts: 'host2:role=worker,host3:role=worker:group=g02,host4:role=standby:group=g02' sap_hana_install_sid: 'H01' - sap_hana_install_instance_number: '00' + sap_hana_install_instance_nr: '00' roles: - sap_hana_install ``` @@ -228,7 +234,7 @@ Sample Ansible Playbook Execution sap_hana_install_common_master_password: 'NewPass$321' sap_hana_install_root_password: 'NewPass$321' sap_hana_install_sid: 'H01' - sap_hana_install_instance_number: '00' + sap_hana_install_instance_nr: '00' roles: - sap_hana_install ``` @@ -242,7 +248,7 @@ You can find more complex playbooks in directory `playbooks` of the collection ` #### Perform Initial Checks These checks are only performed if `sap_hana_install_force` is set to `true`. Its default value is `false` -- If variable `sap_hana_install_check_sidadm_user` is undefined or set to `y`: Check if user sidadm exists. If yes, +- If variable `sap_hana_install_check_sidadm_user` is undefined or set to `yes`: Check if user sidadm exists. If yes, abort the role. - Check if `/usr/sap/hostctrl/exe/saphostctrl` exists and get info on running HANA instances. @@ -303,7 +309,7 @@ in a temporary directory for use by the hdblcm command in the next step. - Set Log Mode key to overwrite value and apply to system. -- Apply SAP HANA license to the new deployed instance if set to `y`. +- Apply SAP HANA license to the new deployed instance if set to `yes`. - Set expiry of Unix created users to `never`. diff --git a/roles/sap_hana_install/tasks/main.yml b/roles/sap_hana_install/tasks/main.yml index 2ac3810eb..1a8f2eb7a 100644 --- a/roles/sap_hana_install/tasks/main.yml +++ b/roles/sap_hana_install/tasks/main.yml @@ -3,7 +3,7 @@ - name: Rename some variables used by hdblcm configfile ansible.builtin.set_fact: sap_hana_install_sid: "{{ sap_hana_sid | d(sap_hana_install_sid) | d('') }}" - sap_hana_install_number: "{{ sap_hana_instance_number | d(sap_hana_install_instance_number | d(sap_hana_install_number) | d('')) }}" + sap_hana_install_number: "{{ sap_hana_instance_number | d(sap_hana_install_instance_nr) | d(sap_hana_install_instance_number) | d(sap_hana_install_number) | d('') }}" sap_hana_install_master_password: "{{ sap_hana_install_common_master_password | d(sap_hana_install_master_password) }}" sap_hana_install_system_usage: "{{ sap_hana_install_env_type | d(sap_hana_install_system_usage) }}" sap_hana_install_restrict_max_mem: "{{ sap_hana_install_mem_restrict | d(sap_hana_install_restrict_max_mem) }}" diff --git a/roles/sap_hana_install/tasks/pre_install.yml b/roles/sap_hana_install/tasks/pre_install.yml index 56e1339dc..3e20526c0 100644 --- a/roles/sap_hana_install/tasks/pre_install.yml +++ b/roles/sap_hana_install/tasks/pre_install.yml @@ -83,6 +83,13 @@ - '/hana/data' tags: sap_hana_install_chown_hana_directories + # SELinux is not currently supported by SAP using SLES4SAP + # This is a workaround to avoid change to default to enable SELinux + - name: SAP HANA Pre Install - Ensure SELinux does not execute for SLES + ansible.builtin.set_fact: + sap_hana_install_modify_selinux_labels: false + when: ansible_os_family == "Suse" + - name: SAP HANA Pre Install - Configure '/hana' SELinux file contexts ansible.builtin.include_role: name: '{{ sap_hana_install_system_roles_collection }}.selinux' diff --git a/roles/sap_hana_preconfigure/tasks/RedHat/generic/configure-selinux.yml b/roles/sap_hana_preconfigure/tasks/RedHat/generic/configure-selinux.yml index 1c59a7e4e..fa2905ba2 100644 --- a/roles/sap_hana_preconfigure/tasks/RedHat/generic/configure-selinux.yml +++ b/roles/sap_hana_preconfigure/tasks/RedHat/generic/configure-selinux.yml @@ -1,6 +1,6 @@ --- -- name: SAP HANA Pre Install - Configure SELinux file contexts +- name: SELinux - Configure SELinux file contexts ansible.builtin.include_role: name: '{{ sap_hana_preconfigure_system_roles_collection }}.selinux' vars: diff --git a/roles/sap_hana_preconfigure/vars/RedHat_9.yml b/roles/sap_hana_preconfigure/vars/RedHat_9.yml index 58e2863d0..11c862ef9 100644 --- a/roles/sap_hana_preconfigure/vars/RedHat_9.yml +++ b/roles/sap_hana_preconfigure/vars/RedHat_9.yml @@ -192,8 +192,8 @@ __sap_hana_preconfigure_packages: - chkconfig # package compat-openssl11: needed for HANA scale-out and when configuring HANA backup on Azure - compat-openssl11 -# required for SAP HANA on RHEL 9: - - libxcrypt-compat +# package libxcrypt-compat: needed SAP HANA and also by sapstartsrv on RHEL 9: +# - libxcrypt-compat # now installed by role sap_general_preconfigure, see also SAP note 3108316, version 4. # For support purposes: # package graphwiz: graph visualization toos, for supportability) - graphviz diff --git a/roles/sap_install_media_detect/README.md b/roles/sap_install_media_detect/README.md index 32912f80f..d936b39bd 100644 --- a/roles/sap_install_media_detect/README.md +++ b/roles/sap_install_media_detect/README.md @@ -16,6 +16,27 @@ RAR files. See the comments and examples for the RAR file handling in `defaults/ when the role was run, it will remain enabled. If the EPEL repo was not present, the associated GPG key will be removed and the EPEL repo will be disabled as the last task. +## Execution Flow + +- At the beginning of the execution of the role, a new tool `sapfile` is pushed to a temporary directory on the managed node. +- Also a package which contains a command for extracting and listing content of files of type `RAR` is installed. +- The next step is to check if source and/or target directories exist. If role parameter `sap_install_media_detect_target_directory` is defined, files will later be copied from `sap_install_media_detect_source_directory`. This is the `remote_dir` case. +- If the system on which the `sap_install_media_detect_source_directory` is not writable, the role would normally fail because one or both of the following conditions are not met: + - The SAPCAR EXE file is not executable. + - There are one or more `ZIP` or `RAR` files without extension. +- In this `remote_dir` case, to make sure the role does not fail, it needs to be run first on the node on which `sap_install_media_detect_source_directory` is writable, with role parameter `sap_install_media_detect_file_server_only` set to `true` so the role will not perform and further file detection activities. +- After the SAPCAR EXE file is executable and there are no more `ZIP` or `RAR` files without extension, the role can be called on a managed node where `sap_install_media_detect_source_directory` is not writable. +- A new list of all files with the correct final file names will then be created, and for each of the files, the SAP file types are determined using the `sapfile` tool, either using the file names or - if this information is not sufficient - from information inside the file. +- We then assert that there is at least (or exactly, depending on the file type) one file available for each of the `sap_install_media_detect_*` parameters. For example, if `sap_install_media_detect_kernel_db` is set to `saphana`, then there must be one SAP Kernel DB dependent file for SAP HANA. +- In case of `remote_dir`, the next step is to copy all files from `sap_install_media_detect_source_directory` to `sap_install_media_detect_target_directory`. +- Then we extract files which are configured in `sapfile` to be extracted, and copy or move files which are configured in `sapfile` to be copied or moved. Certain files like `SAPCAR*.EXE` and the SAP Host Agent will be copied to two different directories. +- Once all necessary files have been extracted and all files are copied or moved to where we want them to be, we are using the Ansible find module to identify the different file types by using file or directory name patterns. +- The last step is to fill all required `sap_swpm` parameters from the result of the previous find step, and display all the variables. + +## Variables and Parameters + +See the file `defaults/main.yml`. + ## Dependencies This role does not depend on any other Ansible Role. @@ -23,11 +44,21 @@ This role does not depend on any other Ansible Role. ## Tags With the following tags, the role can be called to perform certain activities only: +- tag `sap_install_media_detect_zip_handling`: Only perform the task for enabling the listing and extracting of files of type `ZIP`. - tag `sap_install_media_detect_rar_handling`: Only perform the tasks for enabling the listing and extracting of files of type `RAR`. This includes enabling and disabling the EPEL repo for RHEL systems, if desired. -- tag `sap_install_media_detect_add_rar_extension`: Only add `.rar` to any files in `sap_install_media_detect_source_directory` which are of type `RAR` and have no ending. Needs to be used with tag `sap_install_media_detect_create_file_list`. +- tag `sap_install_media_detect_add_file_extension`: Add file name extensions to any files in `sap_install_media_detect_source_directory` which are of type `RAR` or `ZIP` and have no ending. Needs to be used with tag `sap_install_media_detect_create_file_list_phase_1`. - tag `sap_install_media_detect_check_directories`: Find out if the directory `sap_install_media_detect_target_directory` or `sap_install_media_detect_source_directory` is writable. -- tag `sap_install_media_detect_create_file_list`: Only create a list of all files in `sap_install_media_detect_source_directory`, and create a list of any files which have no ending and are of type `RAR`. +- tag `sap_install_media_detect_provide_sapfile_utility `: Provides the sapfile utility on the managed node. This tool is required for determining the SAP file type. +- tag `sap_install_media_detect_create_file_list_phase_1`: Create a list of all files in `sap_install_media_detect_source_directory`, and create a list of any files which have no ending and are of type `RAR`. +- tag `sap_install_media_detect_create_file_list_phase_2`: Create a final list of all required files in `sap_install_media_detect_source_directory` or `sap_install_media_detect_target_directory` (if that one is defined) +- tag `sap_install_media_detect_organize_files`: Copies all required files from `sap_install_media_detect_source_directory` or `sap_install_media_detect_target_directory` (if that one is defined) and extracts all required files into the target directories if specified by the output of the sapfile command. +- tag `sap_install_media_detect_move_files_to_main_directory`: Move SAP archive files from level 1 subdirectories (where they might reside after the role has been used initially) back to the main software directory. Those subdirectories will afterwards be removed. This is to make sure the role will produce the same result no matter how often it is executed (= idempotency). The directories with pattern `*_extracted` will remain in place. +- tag `sap_install_media_detect_find_files_after_extraction`: Finds all required files after they have been extracted so the final variables can be filled in the next step. +- tag `sap_install_media_detect_set_global_vars`: Set all final variables for later use by Ansible roles or tasks. + +Note: After running the role with the following four tags, the SAP archive files will be in the same place as before running the role the first time. The directories with pattern `*_extracted` will remain in place. +`sap_install_media_detect_provide_sapfile_utility,sap_install_media_detect_check_directories,sap_install_media_detect_create_file_list_phase_1,sap_install_media_detect_move_files_to_main_directory` ## License diff --git a/roles/sap_install_media_detect/defaults/main.yml b/roles/sap_install_media_detect/defaults/main.yml index 3c57ea55e..a1a1fe264 100644 --- a/roles/sap_install_media_detect/defaults/main.yml +++ b/roles/sap_install_media_detect/defaults/main.yml @@ -16,37 +16,93 @@ sap_install_media_detect_use_rpm_key_module_for_removing_the_key: true # If this role is running on a system on which the SAP software is to be installed, set the following to false. sap_install_media_detect_file_server_only: false +# Fully qualified path to the sapcar program. If not specified, the sapcar program (or a link with the name sapcar, pointing to +# the actual SAPCAR*EXE program) is expected to be located in one of the PATH directories. +#sap_install_media_detect_sapcar_path: '/usr/local/bin/sapcar' + +# Fully qualified path to the program for listing RAR files, including the argument for listing files. If not specified, +# the lsar program (or a link with the name lsar, pointing to the actual lsar program) is expected to be located in one of +# the PATH directories. +# If sap_install_media_detect_rar_package is set to 'EPEL', this variable is not used. +#sap_install_media_detect_rar_list: '/usr/bin/lsar' +sap_install_media_detect_rar_list: '/usr/bin/unrar lb' + +# Fully qualified path to the program for extracting RAR files, including the argument for extracting files. If not specified, +# the unar program (or a link with the name unar, pointing to the actual unar program) is expected to be located in one of +# the PATH directories. +# If sap_install_media_detect_rar_package is set to 'EPEL', this variable is not used. +#sap_install_media_detect_rar_extract: '/usr/bin/unar' +sap_install_media_detect_rar_extract: '/usr/bin/unrar x' + +# Fully qualified path to an additional argument to the program for extracting RAR files, for specifying the directory into +# which the archive is to be extracted. Needs to be empty or start with a space character. +# If sap_install_media_detect_rar_package is set to 'EPEL', this variable is not used. +#sap_install_media_detect_rar_extract_directory_argument: ' -o' +sap_install_media_detect_rar_extract_directory_argument: '' + # Directory where the SAP software is located sap_install_media_detect_source_directory: /software # Directory where the SAP software is located after the role is run, if different from sap_install_media_detect_source_directory #sap_install_media_detect_target_directory: /software_local +# Create target directory if it does not yet exist. If set to false, perform a check only +sap_install_media_detect_create_target_directory: true + # If there are two files of the same RAR or ZIP type, one with and one without suffix, the following parameter will determine what # the role will do for such a file: skip the file renaming, fail, or overwrite the file with the suffix by the file without suffix sap_install_media_detect_rename_target_file_exists: 'skip' #sap_install_media_detect_rename_target_file_exists: 'fail' #sap_install_media_detect_rename_target_file_exists: 'overwrite' -# local_dir, remote_dir (e.g. NFS, s3fuse) -#sap_install_media_detect_source: local_dir +# If you want the role to not extract archives which have the extract flag set, set the following parameter to `false`. +sap_install_media_detect_extract_archives: true -# If the following parameter is set to true and the target directory for the extracted files (= *_extracted) already exists, -# the extraction of the corresponding file will be skipped. If set to false, target directories will be removed initially, -# forcing a fresh extraction, including re-creation of the target directory. -sap_install_media_detect_skip_extraction_if_target_dir_exists: false +# If you want the role to not move or copy archive files to the `target_dir` subdirectories, set the following parameter to `false`. +sap_install_media_detect_move_or_copy_archives: true -# saphana, sapase, sapmaxdb, oracledb, ibmdb2 -sap_install_media_detect_db: "saphana" +# By default, the presence of at least one file for each file type according to the configured role parameters is asserted. Set the +# following parameter to 'false' to skip this step. +sap_install_media_detect_assert_after_sapfile: true -sap_install_media_detect_swpm: true -sap_install_media_detect_hostagent: true -sap_install_media_detect_igs: true -sap_install_media_detect_kernel: true +sap_install_media_detect_db: '' # saphana, sapase, sapmaxdb, oracledb, ibmdb2 +sap_install_media_detect_db_client: '' # saphana, sapase, sapmaxdb, oracledb, ibmdb2 +sap_install_media_detect_swpm: false +sap_install_media_detect_hostagent: false +sap_install_media_detect_igs: false +sap_install_media_detect_kernel: false +sap_install_media_detect_kernel_db: '' # saphana, sapase, sapmaxdb, oracledb, ibmdb2 +# (only necessary if there is more than one SAPEXEDB file in the source directory) sap_install_media_detect_webdisp: false +sap_install_media_detect_mpstack: false +sap_install_media_detect_export: '' # saps4hana, sapbw4hana, sapecc, sapecc_ides, +# sapnwas_abap, sapnwas_java, sapsolman_abap, sapsolman_java + +# Example for parameter settings for SAP S/4HANA: +#sap_install_media_detect_db: 'saphana' # saphana, sapase, sapmaxdb, oracledb, ibmdb2 +#sap_install_media_detect_db_client: 'saphana' # saphana, sapase, sapmaxdb, oracledb, ibmdb2 +#sap_install_media_detect_swpm: true +#sap_install_media_detect_hostagent: true +#sap_install_media_detect_igs: true +#sap_install_media_detect_kernel: true +#sap_install_media_detect_kernel_db: 'saphana' # saphana, sapase, sapmaxdb, oracledb, ibmdb2 +# (only necessary if there is more than one SAPEXEDB file in the source directory) +#sap_install_media_detect_webdisp: false +#sap_install_media_detect_export: 'saps4hana' # saps4hana, sapbw4hana, sapecc, sapecc_ides, +# sapnwas_abap, sapnwas_java, sapsolman_abap, sapsolman_java -# saps4hana, sapecc, sapecc_ides, sapbw4hana, sapnwas_abap, sapnwas_java -sap_install_media_detect_export: +# Example for parameter settings for SAP ERP 6.0 EHP8 with SAP HANA database: +#sap_install_media_detect_db: 'saphana' # saphana, sapase, sapmaxdb, oracledb, ibmdb2 +#sap_install_media_detect_db_client: 'saphana' # saphana, sapase, sapmaxdb, oracledb, ibmdb2 +#sap_install_media_detect_swpm: true +#sap_install_media_detect_hostagent: true +#sap_install_media_detect_igs: true +#sap_install_media_detect_kernel: true +#sap_install_media_detect_kernel_db: 'saphana' # saphana, sapase, sapmaxdb, oracledb, ibmdb2 +# (only necessary if there is more than one SAPEXEDB file in the source directory) +#sap_install_media_detect_webdisp: false +#sap_install_media_detect_export: 'sapecc' # saps4hana, sapbw4hana, sapecc, sapecc_ides, +# sapnwas_abap, sapnwas_java, sapsolman_abap, sapsolman_java # e.g. /db_backup sap_install_media_detect_backup_directory: diff --git a/roles/sap_install_media_detect/files/tmp/sapfile b/roles/sap_install_media_detect/files/tmp/sapfile new file mode 100755 index 000000000..6a37c1f7d --- /dev/null +++ b/roles/sap_install_media_detect/files/tmp/sapfile @@ -0,0 +1,394 @@ +#!/bin/bash +# sapfile: Determine and display SAP file type +# +# Copyright 2023 Bernd Finger, Red Hat +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +set -o nounset +set -o pipefail + +usage () { + echo "sapfile: Determine and display SAP file type. If unknown, call the file command." + echo "Usage: sapfile [OPTION...] [FILE...]" + echo "Determine and display type of SAP FILEs, optionally followed by additional information." + echo " -h|--help display this help and exit" + echo " -H|--header display a column header" + echo " -l|--long long listing: also display the file type, taken from the output of the file command" + echo " -e|--extra-long extra long listing: display all information required by role sap_install_media_detect" + echo " --lsar_file= the name of the program to list the content of a RAR file, if different from 'lsar'," + echo " either as the name of a file in one of the PATH directories or as an FQPN." + echo " When specifying the 'unrar' program, it will be called with option 'lb'." + echo " --sapcar_file= the name of the sapcar program, if different from 'sapcar', either as the name of a file" + echo " in one of the PATH directories or as an FQPN." + echo "" + echo "Requires:" + echo "- lsar (program to list the content of a RAR package, e.g. as part of the 'unar' package from the EPEL RHEL repo)" + echo "- zipinfo (contained in the unzip RHEL package)" + echo "- sapcar (SAP program to handle sapcar files; typical filename: SAPCAR_1115-70006178.EXE)" +} + +# defaults: +_DELIMITER=";" + +# option defaults: +_DISPLAY_FILE_TYPE="n" +_DISPLAY_ALL_INFO="n" +_DISPLAY_HEADER="n" +_SAPCAR_FILE='sapcar' +_LSAR_FILE='lsar' + +if [[ ${#} == 0 ]]; then + usage + exit 1 +fi + +options=":leHh-:" +while getopts "$options" opt; do + case ${opt} in + -) + case "${OPTARG}" in + long) + _DISPLAY_FILE_TYPE="y" + ;; + extra-long) + _DISPLAY_ALL_INFO="y" + ;; + header) + _DISPLAY_HEADER="y" + ;; + lsar_file) + if [[ ${!OPTIND-x} == x ]]; then + usage + exit 0 + fi + _LSAR_FILE="${!OPTIND}" + OPTIND=$(( OPTIND + 1 )) + ;; + lsar_file=*) + _LSAR_FILE=${OPTARG#*=} + opt=${OPTARG%="${_LSAR_FILE}"} + ;; + sapcar_file) + if [[ ${!OPTIND-x} == x ]]; then + usage + exit 0 + fi + _SAPCAR_FILE="${!OPTIND}" + OPTIND=$(( OPTIND + 1 )) + ;; + sapcar_file=*) + _SAPCAR_FILE=${OPTARG#*=} + opt=${OPTARG%="${_SAPCAR_FILE}"} + ;; + help) + usage + exit 0 + ;; + *) + if [[ "$OPTERR" = 1 ]] && [[ "${options:0:1}" != ":" ]]; then + echo "Invalid option -${OPTARG}" + usage + fi + exit 0 + ;; + esac;; + l) + _DISPLAY_FILE_TYPE="y" + ;; + e) + _DISPLAY_ALL_INFO="y" + ;; + H) + _DISPLAY_HEADER="y" + ;; + h) + usage + exit 0 + ;; + \?) + echo "Invalid option -$OPTARG" + usage + exit 0 + ;; + esac +done +shift "$((OPTIND-1))" + +if [[ "${_LSAR_FILE}" == *"lsar"* ]]; then + _LSAR_COMMAND="${_LSAR_FILE}" +elif [[ "${_LSAR_FILE}" == *"unrar"* ]]; then + _LSAR_COMMAND="${_LSAR_FILE} lb" +fi + +# Identify sapcar: Try using sapcar in PATH or SAPCAR*EXE in current directory +if [[ ${_SAPCAR_FILE}. == "sapcar." ]]; then + which sapcar >/dev/null 2>&1 + RC1=$? + if [[ ${RC1} -eq 0 ]]; then + _SAPCAR_FILE=$(which sapcar) + else + _SAPCAR_TEST=$(set -o pipefail && ls -1tr ./SAPCAR*EXE 2>/dev/null) + RC2=$? + if [[ ${RC2} != 0 ]]; then + echo "No file with name SAPCAR*EXE in current directory found." + echo "Note: sapfile needs sapcar in PATH or SAPCAR*EXE in current directory - matching the system's CPU architecture - to function properly." + echo + usage + exit 1 + else + _SAPCAR_ARCH=$(for sapcar_any in ${_SAPCAR_TEST}; do + file ${sapcar_any} | awk '{ + split ($0, a, ":"); split (a[2], b, ","); sub ("^ ", "", b[2]); + sub ("x86-64", "x86_64", b[2]); + if (index (b[2], "64-bit PowerPC") > 0) { + if ((index (b[3], "GNU/Linux") > 0)||(index (b[4], "GNU/Linux") > 0)) {sub ("64-bit PowerPC", "ppc64le", b[2])}; + if ((index (b[3], "SYSV") > 0)||(index (b[4], "SYSV") > 0)) {sub ("64-bit PowerPC", "ppc64", b[2])}; + } + sub ("IBM S/390", "s390x", b[2]); + printf ("%s %s %s\n", a[1], b[2], b[3])}'; + done | awk '/'$(uname -m)'/{print $1}' | tail -1) + if [[ ${_SAPCAR_ARCH}. == . ]]; then + echo "No file SAPCAR*EXE for the CPU architecture '$(uname -m)' in current directory found." + echo "Note: sapfile needs sapcar in PATH or SAPCAR*EXE in current directory - matching the system's CPU architecture - to function properly." + echo + usage + exit 1 + else + _SAPCAR_FILE=${_SAPCAR_ARCH} + fi + fi + fi +fi + +_GENERIC_FILE_TYPE="other" + +if [[ ${_DISPLAY_HEADER}. == "y." ]]; then + if [[ ${_DISPLAY_ALL_INFO}. == "y." ]]; then + printf "%s;%s;%s;%s;%s;%s;%s\n" "filename" "sap_file_type" "target_dir" "extraction_dir" "file_type" "extract" "copy" + else + if [[ ${_DISPLAY_FILE_TYPE}. == "y." ]]; then + printf "%-40s %-24s %-6s\n" "filename:" "sap_file_type" "file_type" + else + printf "%-40s %-24s\n" "filename:" "sap_file_type" + fi + fi +fi + +for _FILE in "$@"; do + _FILE_OUTPUT=$(file "${_FILE}" | sed 's,'"${_FILE}"': ,,') + if [[ ${_FILE_OUTPUT}. == "data." ]] && [[ (${_FILE##*.} == "SAR" || ${_FILE##*.} == "sar") ]]; then + _GENERIC_FILE_TYPE="sapcar" + _list_content="${_SAPCAR_FILE} -tvf" + else + _GENERIC_FILE_TYPE=$(echo "${_FILE_OUTPUT}" | awk ' + BEGIN{_file_type="other"} + /RAR self-extracting archive/{_file_type="rarexe"} + /RAR archive data/{_file_type="rar"} + /Zip archive data/{_file_type="zip"} + /SAPCAR archive data/{_file_type="sapcar"} + /XML/&&/ASCII/{_file_type="xml"} + /directory/{_file_type="dir"} + END{print _file_type}') + if [[ ${_GENERIC_FILE_TYPE}. == "rarexe." ]]; then + _list_content="${_LSAR_COMMAND}" + elif [[ ${_GENERIC_FILE_TYPE}. == "rar." ]]; then + _list_content="${_LSAR_COMMAND}" + elif [[ ${_GENERIC_FILE_TYPE}. == "zip." ]]; then + _list_content="zipinfo -1" + elif [[ ${_GENERIC_FILE_TYPE}. == "sapcar." ]]; then + _list_content="${_SAPCAR_FILE} -tvf" + elif [[ ${_GENERIC_FILE_TYPE}. == "xml." ]]; then + _list_content="cat" + elif [[ ${_GENERIC_FILE_TYPE}. == "dir." ]]; then + _list_content="" + fi + fi + if [[ ${_DISPLAY_ALL_INFO}. == "y." ]]; then + printf "%s%s" "${_FILE}" "${_DELIMITER}" + else + printf "%-40s " "${_FILE}": + fi + + if [[ ! -e "${_FILE}" ]]; then + echo "No such file or directory." + exit 1 + fi + + SAP_FILE_TYPE_FROM_FILENAME=$(echo "${_FILE}" | awk ' + BEGIN{_sap_file_type="look_inside"} + /SAPCAR/&&/\.EXE/{_sap_file_type="sapcar"} + /IMDB_SERVER/&&/\.SAR/{_sap_file_type="saphana"} + /IMDB_CLIENT/&&/\.SAR/{_sap_file_type="saphana_client"} + !/IMDB_SERVER/&&!/IMDB_CLIENT/&&/IMDB/&&/\.SAR/{_sap_file_type="saphana_other"} + /SWPM/&&/\.SAR/{_sap_file_type="sap_swpm"} + /SAPHOSTAGENT/&&/\.SAR/{_sap_file_type="sap_hostagent"} + /SAPEXE_/{_sap_file_type="sap_kernel"} + /SAPEXEDB_/{_sap_file_type="sap_kernel_db"} + /igsexe/||/igshelper/{_sap_file_type="sap_igs"} + /SAPWEBDISP_/{_sap_file_type="sap_webdisp"} + /SAPJVM/{_sap_file_type="sap_jvm"} + /ASEBC/{_sap_file_type="sapase_client"} + /COMPLETE/{_sap_file_type="saphana_backup"} + /S4/&&/LANG/{_sap_file_type="sap_s4hana_lang"} + /S4/&&/EXPORT/{_sap_file_type="sap_export_s4hana"} + /BW4/&&/EXPORT/{_sap_file_type="sap_export_bw4hana"} + /VCH/&&/\.SAR/{_sap_file_type="saphana_vch_afl"} + END{print _sap_file_type}') + if [[ ${SAP_FILE_TYPE_FROM_FILENAME}. == "sap_kernel_db." ]]; then + SAP_FILE_TYPE_FROM_FILENAME=$(eval "${_list_content}" "${_FILE}" | awk ' + /exe_/&&/\.lst/{gsub ("exe_", ""); gsub ("\\.lst", ""); db_type=$NF} + END{printf ("sap_kernel_db_%s\n", db_type)}') + fi + + if [[ ${SAP_FILE_TYPE_FROM_FILENAME}. != "look_inside." ]]; then + _SAP_FILE_TYPE=${SAP_FILE_TYPE_FROM_FILENAME} + else + if [[ ${_GENERIC_FILE_TYPE}. == "dir." ]]; then + _SAP_FILE_TYPE=${_FILE_OUTPUT} + elif [[ ${_GENERIC_FILE_TYPE}. == "rarexe." || + ${_GENERIC_FILE_TYPE}. == "rar." || + ${_GENERIC_FILE_TYPE}. == "zip." || + ${_GENERIC_FILE_TYPE}. == "sapcar." || + ${_GENERIC_FILE_TYPE}. == "xml." ]]; then + _SAP_FILE_TYPE=$(eval "${_list_content}" "${_FILE}" | awk ' + BEGIN{_sap_file_type="sap_unknown"} + /BD_SYBASE_ASE/{_sap_file_type="sapase"} + /ASEBC/{_sap_file_type="sapase_client"} + /MaxDB_7.9/{_sap_file_type="sapmaxdb"} + /19cinstall.sh/{_sap_file_type="oracledb"} + /OCL_LINUX_X86_64/{_sap_file_type="oracledb_client"} + /brtools/{_sap_file_type="oracledb_tools"} + /db2setup/{_sap_file_type="ibmdb2"} + /db6_update_client.sh/{_sap_file_type="ibmdb2_client"} + /db2aese_c.lic/{_sap_file_type="ibmdb2_license"} + /DATA_UNITS\/EXPORT/{_sap_file_type="sap_export_ecc"} + /EXP[0-9]/{_sap_file_type="sap_export_ecc_ides"} + /DATA_UNITS\/EXP[0-9]/{_sap_file_type="sap_export_nwas_abap"} + /DATA_UNITS\/JAVA_EXPORT_JDMP/{_sap_file_type="sap_export_nwas_java"} + /DATA_UNITS\/SOLMAN/&&/_JAVA_UT/{_sap_file_type="sap_export_solman_java"} + /0 && length(number)>0) { + a=substr(product_id, index(product_id, "4")+1, index(product_id, "1")-(index(product_id, "4")+1)); + if (a=="fnd" || a=="hanaop"){_sap_file_type="sap_export_s4hana"} + } + } + END{print _sap_file_type}') + fi + else + _SAP_FILE_TYPE="sap_unknown" + fi + fi + + _TARGET_DIRECTORY=${_SAP_FILE_TYPE} + _EXTRACTION_DIRECTORY=${_SAP_FILE_TYPE}_extracted + _EXTRACT="y" + _COPY="n" + + case ${_SAP_FILE_TYPE} in + directory) + _EXTRACT="n" + _EXTRACTION_DIRECTORY="none" + ;; + sapcar) + _TARGET_DIRECTORY="auto" + _EXTRACTION_DIRECTORY="none" + _EXTRACT="n" + _COPY="y" + ;; + sap_hostagent) + _TARGET_DIRECTORY="auto" + _EXTRACTION_DIRECTORY="none" + _EXTRACT="n" + _COPY="y" + ;; + saphana_client) + _TARGET_DIRECTORY="auto" + _EXTRACTION_DIRECTORY="sap_hana_client_extracted" + _EXTRACT="y" + _COPY="y" + ;; + sapase|sapase_client) + _TARGET_DIRECTORY="sapase" + ;; + sapmaxdb) + ;; + oracledb|oracledb_client) + _TARGET_DIRECTORY="oracledb" + ;; + oracledb_tools) + _TARGET_DIRECTORY="sap_swpm_download_basket" + _EXTRACTION_DIRECTORY="none" + _EXTRACT="n" + ;; + ibmdb2|ibmdb2_client|ibmdb2_license) + _TARGET_DIRECTORY="ibmdb2" + ;; + saphana|saphana_other|saphana_vch_afl) + _TARGET_DIRECTORY="sap_hana" + _EXTRACTION_DIRECTORY="sap_hana_extracted" + _EXTRACT="y" + ;; + sap_swpm) + _TARGET_DIRECTORY="sap_swpm" + _EXTRACTION_DIRECTORY="none" + _EXTRACT="n" + ;; + sap_kernel*|sap_igs|sap_webdisp|sap_jvm) + _TARGET_DIRECTORY="sap_swpm_download_basket" + _EXTRACTION_DIRECTORY="none" + _EXTRACT="n" + ;; + sap_export_s4hana|sap_export_bw4hana) + _TARGET_DIRECTORY="sap_swpm_download_basket" + _EXTRACTION_DIRECTORY="none" + _EXTRACT="n" + ;; + sap_mp_xml) + _TARGET_DIRECTORY="sap_swpm_download_basket" + _EXTRACTION_DIRECTORY="none" + _EXTRACT="n" + ;; + sap_export*) + ;; + *) + _TARGET_DIRECTORY="sap_swpm_download_basket" + _EXTRACTION_DIRECTORY="none" + _EXTRACT="n" + ;; + esac + + if [[ ${_DISPLAY_ALL_INFO}. == "y." ]]; then + printf "%s%s%s%s%s%s%s%s%s%s%s\n" "${_SAP_FILE_TYPE}" "${_DELIMITER}" "${_TARGET_DIRECTORY}" "${_DELIMITER}" "${_EXTRACTION_DIRECTORY}" "${_DELIMITER}" "${_GENERIC_FILE_TYPE}" "${_DELIMITER}" "${_EXTRACT}" "${_DELIMITER}" "${_COPY}" + else + if [[ ${_DISPLAY_FILE_TYPE}. == "y." ]]; then + printf "%-24s %-6s\n" "${_SAP_FILE_TYPE}" "${_GENERIC_FILE_TYPE}" + else + printf "%-24s\n" "${_SAP_FILE_TYPE}" + fi + fi +done diff --git a/roles/sap_install_media_detect/tasks/cleanup/remove_sapfile_utility.yml b/roles/sap_install_media_detect/tasks/cleanup/remove_sapfile_utility.yml new file mode 100644 index 000000000..0e95e08bb --- /dev/null +++ b/roles/sap_install_media_detect/tasks/cleanup/remove_sapfile_utility.yml @@ -0,0 +1,6 @@ +--- + +- name: SAP Install Media Detect - Prepare - Remove temporary directory + ansible.builtin.file: + path: "{{ __sap_install_media_detect_tmpdir.path }}" + state: absent diff --git a/roles/sap_install_media_detect/tasks/detect_backup_saphana.yml b/roles/sap_install_media_detect/tasks/detect_backup_saphana.yml deleted file mode 100644 index fa7c90219..000000000 --- a/roles/sap_install_media_detect/tasks/detect_backup_saphana.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- - -- name: Identify SAP HANA Backup files - ansible.builtin.find: - paths: "{{ sap_install_media_detect_backup_directory }}" - recurse: true - file_type: directory - patterns: '.*COMPLETE.*' - use_regex: true - register: backup_saphana_find_dir diff --git a/roles/sap_install_media_detect/tasks/detect_export_sapbw4hana.yml b/roles/sap_install_media_detect/tasks/detect_export_sapbw4hana.yml deleted file mode 100644 index 8695a57c0..000000000 --- a/roles/sap_install_media_detect/tasks/detect_export_sapbw4hana.yml +++ /dev/null @@ -1,26 +0,0 @@ ---- - -- name: SAP Install Media Detect - SAP BW/4HANA EXPORT - Create Directories - ansible.builtin.file: - path: "{{ item }}" - state: directory - mode: '0755' - owner: root - group: root - with_items: - - "{{ __sap_install_media_detect_software_main_directory }}/sapbw4hana_export/" - -- name: SAP Install Media Detect - SAP BW/4HANA EXPORT - Identify SAP BW/4HANA EXPORT files - ansible.builtin.find: - paths: "{{ __sap_install_media_detect_software_main_directory }}" - recurse: true - file_type: file - patterns: '.*BW4.*EXPORT.*' - use_regex: true - register: bw4hana_export_files - -- name: SAP Install Media Detect - SAP BW/4HANA EXPORT - Local Directory source - move SAP BW/4HANA EXPORT files - ansible.builtin.command: mv "{{ item.path }}" "{{ __sap_install_media_detect_software_main_directory }}/sapbw4hana_export/{{ item.path | basename }}" - with_items: "{{ bw4hana_export_files.files }}" - when: - - sap_install_media_detect_source == "local_dir" diff --git a/roles/sap_install_media_detect/tasks/detect_export_sapecc.yml b/roles/sap_install_media_detect/tasks/detect_export_sapecc.yml deleted file mode 100644 index 63350993c..000000000 --- a/roles/sap_install_media_detect/tasks/detect_export_sapecc.yml +++ /dev/null @@ -1,164 +0,0 @@ ---- - -- name: SAP Install Media Detect - SAP ECC EXPORT - Get info of directory 'sapecc_export_extracted' - ansible.builtin.stat: - path: "{{ __sap_install_media_detect_software_main_directory }}/sapecc_export_extracted/" - register: __sap_install_media_detect_sapecc_export_extracted_stat - -- name: SAP Install Media Detect - SAP ECC EXPORT - Ensure directory 'sapecc_export_extracted' is absent - ansible.builtin.file: - path: "{{ __sap_install_media_detect_software_main_directory }}/sapecc_export_extracted/" - state: absent - when: - - not sap_install_media_detect_skip_extraction_if_target_dir_exists - -- name: SAP Install Media Detect - SAP ECC EXPORT - Create Directories - ansible.builtin.file: - path: "{{ item }}" - state: directory - mode: '0755' - owner: root - group: root - with_items: - - "{{ __sap_install_media_detect_software_main_directory }}/sapecc_export/" - - "{{ __sap_install_media_detect_software_main_directory }}/sapecc_export_extracted/" - -- name: SAP Install Media Detect - SAP ECC EXPORT - List files in directory - ansible.builtin.command: find . -maxdepth 1 -type f - register: detect_directory_files - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - changed_when: false - -- name: SAP Install Media Detect - SAP ECC EXPORT - Detect ZIP files (including no file extensions), ignore errors - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then echo {{ item }}; fi - register: detect_directory_files_zip - with_items: - - "{{ detect_directory_files.stdout_lines }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - ignore_errors: true - changed_when: false - -- name: SAP Install Media Detect - SAP ECC EXPORT - Detect RAR files (including no file extensions), ignore errors - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'RAR')" ]; then echo {{ item }}; fi - register: detect_directory_files_rar - with_items: - - "{{ detect_directory_files.stdout_lines }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - ignore_errors: true - changed_when: false - -# Reason for noqa: grep -q with pipefail shell option returns 141 instead of 0 -- name: SAP Install Media Detect - SAP ECC EXPORT - Identify SAP ECC EXPORT files # noqa risky-shell-pipe - ansible.builtin.shell: | - if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then - if zipinfo -1 {{ item }} | grep -q 'DATA_UNITS/EXPORT_'; then - echo '{{ item }}' - fi - elif [ ! -z "$(file {{ item }} | grep 'RAR')" ]; then - if eval "{{ sap_install_media_detect_rar_list }}" {{ item }} | grep -q 'DATA_UNITS/EXPORT_'; then - echo '{{ item }}' - fi - fi - register: detect_directory_files_ecc_export - changed_when: "item | length > 0" - with_items: - - "{{ detect_directory_files_zip.results | map(attribute='stdout') | select() }}" - - "{{ detect_directory_files_rar.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - -# Reason for noqa: Difficult to determine the change status in the shell command sequence -- name: SAP Install Media Detect - SAP ECC EXPORT - If any ZIP, then extract the SAP ECC Installation Export file (unzip) # noqa no-changed-when - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then unzip {{ item }} -d ./sapecc_export_extracted ; fi - with_items: - - "{{ detect_directory_files_ecc_export.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - when: (not __sap_install_media_detect_sapecc_export_extracted_stat.stat.exists) or - ( __sap_install_media_detect_sapecc_export_extracted_stat.stat.exists and not - sap_install_media_detect_skip_extraction_if_target_dir_exists) - -# Reason for noqa: Difficult to determine the change status in the shell command sequence -- name: SAP Install Media Detect - SAP ECC EXPORT - Find self-extracting RAR EXE (parent RAR file) and extract SAP ECC Installation Export files # noqa no-changed-when - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'RAR self-extracting archive')" ]; then eval "{{ sap_install_media_detect_rar_extract }}" "{{ item }}{{ sap_install_media_detect_rar_extract_argument }}" sapecc_export_extracted/ ; fi - with_items: - - "{{ detect_directory_files_ecc_export.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - when: (not __sap_install_media_detect_sapecc_export_extracted_stat.stat.exists) or - ( __sap_install_media_detect_sapecc_export_extracted_stat.stat.exists and not - sap_install_media_detect_skip_extraction_if_target_dir_exists) - -- name: SAP Install Media Detect - SAP ECC EXPORT - Identify SAP ECC Export extracted - ansible.builtin.find: - paths: "{{ __sap_install_media_detect_software_main_directory }}/sapecc_export_extracted" - recurse: true - file_type: directory - patterns: '.*DATA_UNITS.*' - use_regex: true - register: detect_directory_export_extracted - -- name: SAP Install Media Detect - SAP ECC EXPORT - Local Directory source - re-list files in directory - ansible.builtin.command: find . -maxdepth 1 -type f - register: detect_directory_files - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - changed_when: false - when: - - sap_install_media_detect_source == "local_dir" - -- name: SAP Install Media Detect - SAP ECC EXPORT - Local Directory source - re-detect ZIP files (including no file extensions), ignore errors - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then echo {{ item }}; fi - register: detect_directory_files_zip_repeated -# changed_when: "item.stdout | length > 0" - with_items: - - "{{ detect_directory_files.stdout_lines }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - ignore_errors: true - when: - - sap_install_media_detect_source == "local_dir" - -- name: SAP Install Media Detect - SAP ECC EXPORT - Local Directory source - re-detect RAR files (including no file extensions), ignore errors - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'RAR')" ]; then echo {{ item }}; fi - register: detect_directory_files_rar_repeated -# changed_when: "item.stdout | length > 0" - with_items: - - "{{ detect_directory_files.stdout_lines }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - ignore_errors: true - when: - - sap_install_media_detect_source == "local_dir" - -# Reason for noqa: grep -q with pipefail shell option returns 141 instead of 0 -- name: SAP Install Media Detect - SAP ECC EXPORT - Local Directory source - re-identify SAP ECC EXPORT files # noqa risky-shell-pipe - ansible.builtin.shell: | - if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then - if zipinfo -1 {{ item }} | grep -q 'DATA_UNITS/EXPORT_' ; then - echo '{{ item }}' - fi - elif [ ! -z "$(file {{ item }} | grep 'RAR')" ]; then - if eval "{{ sap_install_media_detect_rar_list }}" {{ item }} | grep -q 'DATA_UNITS/EXPORT_'; then - echo '{{ item }}' - fi - fi - register: detect_directory_files_ecc_export_repeated - changed_when: "item | length > 0" - with_items: - - "{{ detect_directory_files_zip_repeated.results | map(attribute='stdout') | select() }}" - - "{{ detect_directory_files_rar_repeated.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - when: - - sap_install_media_detect_source == "local_dir" - -- name: SAP Install Media Detect - SAP ECC EXPORT - Local Directory source - move SAP ECC EXPORT compressed archive files - ansible.builtin.command: mv "{{ __sap_install_media_detect_software_main_directory }}/{{ item }}" "{{ __sap_install_media_detect_software_main_directory }}/sapecc_export/{{ item }}" - with_items: - - "{{ detect_directory_files_ecc_export_repeated.results | map(attribute='stdout') | select() }}" - when: - - sap_install_media_detect_source == "local_dir" diff --git a/roles/sap_install_media_detect/tasks/detect_export_sapecc_ides.yml b/roles/sap_install_media_detect/tasks/detect_export_sapecc_ides.yml deleted file mode 100644 index 9279586bf..000000000 --- a/roles/sap_install_media_detect/tasks/detect_export_sapecc_ides.yml +++ /dev/null @@ -1,164 +0,0 @@ ---- - -- name: SAP Install Media Detect - SAP ECC IDES EXPORT - Get info of directory 'sapecc_ides_export_extracted' - ansible.builtin.stat: - path: "{{ __sap_install_media_detect_software_main_directory }}/sapecc_ides_export_extracted/" - register: __sap_install_media_detect_sapecc_ides_export_extracted_stat - -- name: SAP Install Media Detect - SAP ECC IDES EXPORT- Ensure directory 'sapecc_ides_export_extracted' is absent - ansible.builtin.file: - path: "{{ __sap_install_media_detect_software_main_directory }}/sapecc_ides_export_extracted/" - state: absent - when: - - not sap_install_media_detect_skip_extraction_if_target_dir_exists - -- name: SAP Install Media Detect - SAP ECC IDES EXPORT - Create Directories - ansible.builtin.file: - path: "{{ item }}" - state: directory - mode: '0755' - owner: root - group: root - with_items: - - "{{ __sap_install_media_detect_software_main_directory }}/sapecc_ides_export/" - - "{{ __sap_install_media_detect_software_main_directory }}/sapecc_ides_export_extracted/" - -- name: SAP Install Media Detect - SAP ECC IDES EXPORT - List files in directory - ansible.builtin.command: find . -maxdepth 1 -type f - register: detect_directory_files - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - changed_when: false - -- name: SAP Install Media Detect - SAP ECC IDES EXPORT - Detect ZIP files (including no file extensions), ignore errors - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then echo {{ item }}; fi - register: detect_directory_files_zip - with_items: - - "{{ detect_directory_files.stdout_lines }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - ignore_errors: true - changed_when: false - -- name: SAP Install Media Detect - SAP ECC IDES EXPORT - Detect RAR files (including no file extensions), ignore errors - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'RAR')" ]; then echo {{ item }}; fi - register: detect_directory_files_rar - with_items: - - "{{ detect_directory_files.stdout_lines }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - ignore_errors: true - changed_when: false - -# Reason for noqa: grep -q with pipefail shell option returns 141 instead of 0 -- name: SAP Install Media Detect - SAP ECC IDES EXPORT - Identify SAP ECC IDES EXPORT files # noqa risky-shell-pipe - ansible.builtin.shell: | - if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then - if zipinfo -1 {{ item }} | grep -Eq '*EXP[0-9]'; then - echo '{{ item }}' - fi - elif [ ! -z "$(file {{ item }} | grep 'RAR')" ]; then - if eval "{{ sap_install_media_detect_rar_list }}" {{ item }} | grep -Eq '*EXP[0-9]'; then - echo '{{ item }}' - fi - fi - register: detect_directory_files_ecc_export - changed_when: "item | length > 0" - with_items: - - "{{ detect_directory_files_zip.results | map(attribute='stdout') | select() }}" - - "{{ detect_directory_files_rar.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - -# Reason for noqa: Difficult to determine the change status in the shell command sequence -- name: SAP Install Media Detect - SAP ECC IDES EXPORT - If any ZIP, then extract the SAP ECC Installation Export file (unzip) # noqa no-changed-when - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then unzip {{ item }} -d ./sapecc_ides_export_extracted ; fi - with_items: - - "{{ detect_directory_files_ecc_export.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - when: (not __sap_install_media_detect_sapecc_ides_export_extracted_stat.stat.exists) or - ( __sap_install_media_detect_sapecc_ides_export_extracted_stat.stat.exists and not - sap_install_media_detect_skip_extraction_if_target_dir_exists) - -# Reason for noqa: Difficult to determine the change status in the shell command sequence -- name: SAP Install Media Detect - SAP ECC IDES EXPORT - Find self-extracting RAR EXE (parent RAR file) and extract SAP ECC Installation Export files # noqa no-changed-when - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'RAR self-extracting archive')" ]; then eval "{{ sap_install_media_detect_rar_extract }}" "{{ item }}{{ sap_install_media_detect_rar_extract_argument }}" sapecc_ides_export_extracted/ ; fi - with_items: - - "{{ detect_directory_files_ecc_export.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - when: (not __sap_install_media_detect_sapecc_ides_export_extracted_stat.stat.exists) or - ( __sap_install_media_detect_sapecc_ides_export_extracted_stat.stat.exists and not - sap_install_media_detect_skip_extraction_if_target_dir_exists) - -- name: SAP Install Media Detect - SAP ECC IDES EXPORT - Identify SAP ECC IDES EXPORT extracted - ansible.builtin.find: - paths: "{{ __sap_install_media_detect_software_main_directory }}/sapecc_ides_export_extracted" - recurse: true - file_type: directory - patterns: '.*EXP.*' - use_regex: true - register: detect_directory_export_extracted - -- name: SAP Install Media Detect - SAP ECC IDES EXPORT - Local Directory source - re-list files in directory - ansible.builtin.command: find . -maxdepth 1 -type f - register: detect_directory_files - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - changed_when: false - when: - - sap_install_media_detect_source == "local_dir" - -- name: SAP Install Media Detect - SAP ECC IDES EXPORT - Local Directory source - re-detect ZIP files (including no file extensions), ignore errors - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then echo {{ item }}; fi - register: detect_directory_files_zip_repeated -# changed_when: "item.stdout | length > 0" - with_items: - - "{{ detect_directory_files.stdout_lines }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - ignore_errors: true - when: - - sap_install_media_detect_source == "local_dir" - -- name: SAP Install Media Detect - SAP ECC IDES EXPORT - Local Directory source - re-detect RAR files (including no file extensions), ignore errors - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'RAR')" ]; then echo {{ item }}; fi - register: detect_directory_files_rar_repeated -# changed_when: "item.stdout | length > 0" - with_items: - - "{{ detect_directory_files.stdout_lines }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - ignore_errors: true - when: - - sap_install_media_detect_source == "local_dir" - -# Reason for noqa: grep -q with pipefail shell option returns 141 instead of 0 -- name: SAP Install Media Detect - SAP ECC IDES EXPORT - Local Directory source - re-identify SAP ECC IDES EXPORT files # noqa risky-shell-pipe - ansible.builtin.shell: | - if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then - if zipinfo -1 {{ item }} | grep -Eq '*EXP[0-9]'; then - echo '{{ item }}' - fi - elif [ ! -z "$(file {{ item }} | grep 'RAR')" ]; then - if eval "{{ sap_install_media_detect_rar_list }}" {{ item }} | grep -Eq '*EXP[0-9]'; then - echo '{{ item }}' - fi - fi - register: detect_directory_files_ecc_export_repeated - changed_when: "item | length > 0" - with_items: - - "{{ detect_directory_files_zip_repeated.results | map(attribute='stdout') | select() }}" - - "{{ detect_directory_files_rar_repeated.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - when: - - sap_install_media_detect_source == "local_dir" - -- name: SAP Install Media Detect - SAP ECC IDES EXPORT - Local Directory source - move SAP ECC IDES EXPORT compressed archive files - ansible.builtin.command: mv "{{ __sap_install_media_detect_software_main_directory }}/{{ item }}" "{{ __sap_install_media_detect_software_main_directory }}/sapecc_ides_export/{{ item }}" - with_items: - - "{{ detect_directory_files_ecc_export_repeated.results | map(attribute='stdout') | select() }}" - when: - - sap_install_media_detect_source == "local_dir" diff --git a/roles/sap_install_media_detect/tasks/detect_export_sapnwas_abap.yml b/roles/sap_install_media_detect/tasks/detect_export_sapnwas_abap.yml deleted file mode 100644 index f9ba5a410..000000000 --- a/roles/sap_install_media_detect/tasks/detect_export_sapnwas_abap.yml +++ /dev/null @@ -1,164 +0,0 @@ ---- - -- name: SAP Install Media Detect - SAP NetWeaver AS (ABAP) platform only EXPORT - Get info of directory 'sapnwas_abap_export_extracted' - ansible.builtin.stat: - path: "{{ __sap_install_media_detect_software_main_directory }}/sapnwas_abap_export_extracted/" - register: __sap_install_media_detect_sapnwas_abap_export_extracted_stat - -- name: SAP Install Media Detect - SAP NetWeaver AS (ABAP) platform only EXPORT - Ensure directory 'sapnwas_abap_export_extracted' is absent - ansible.builtin.file: - path: "{{ __sap_install_media_detect_software_main_directory }}/sapnwas_abap_export_extracted/" - state: absent - when: - - not sap_install_media_detect_skip_extraction_if_target_dir_exists - -- name: SAP Install Media Detect - SAP NetWeaver AS (ABAP) platform only EXPORT - Ensure directories exist - ansible.builtin.file: - path: "{{ item }}" - state: directory - mode: '0755' - owner: root - group: root - with_items: - - "{{ __sap_install_media_detect_software_main_directory }}/sapnwas_abap_export/" - - "{{ __sap_install_media_detect_software_main_directory }}/sapnwas_abap_export_extracted/" - -- name: SAP Install Media Detect - SAP NetWeaver AS (ABAP) platform only EXPORT - List files in directory - ansible.builtin.command: find . -maxdepth 1 -type f - register: detect_directory_files - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - changed_when: false - -- name: SAP Install Media Detect - SAP NetWeaver AS (ABAP) platform only EXPORT - Detect ZIP files (including no file extensions), ignore errors - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then echo {{ item }}; fi - register: detect_directory_files_zip - with_items: - - "{{ detect_directory_files.stdout_lines }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - ignore_errors: true - changed_when: no - -- name: SAP Install Media Detect - SAP NetWeaver AS (ABAP) platform only EXPORT - Detect RAR files (including no file extensions), ignore errors - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'RAR')" ]; then echo {{ item }}; fi - register: detect_directory_files_rar - with_items: - - "{{ detect_directory_files.stdout_lines }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - ignore_errors: true - changed_when: no - -# Reason for noqa: grep -q with pipefail shell option returns 141 instead of 0 -- name: SAP Install Media Detect - SAP NetWeaver AS (ABAP) platform only EXPORT - Identify EXPORT files # noqa risky-shell-pipe - ansible.builtin.shell: | - if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then - if zipinfo -1 {{ item }} | grep -q 'DATA_UNITS/EXP'; then - echo '{{ item }}' - fi - elif [ ! -z "$(file {{ item }} | grep 'RAR')" ]; then - if eval "{{ sap_install_media_detect_rar_list }}" {{ item }} | grep -q 'DATA_UNITS/EXP'; then - echo '{{ item }}' - fi - fi - register: detect_directory_files_nwas_abap_export - changed_when: "item | length > 0" - with_items: - - "{{ detect_directory_files_zip.results | map(attribute='stdout') | select() }}" - - "{{ detect_directory_files_rar.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - -# Reason for noqa: Difficult to determine the change status in the shell command sequence -- name: SAP Install Media Detect - SAP NetWeaver AS (ABAP) platform only EXPORT - If any ZIP, then extract the SAP NetWeaver (ABAP) Installation Export file (unzip) # noqa no-changed-when - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then unzip {{ item }} -d ./sapnwas_abap_export_extracted ; fi - with_items: - - "{{ detect_directory_files_nwas_abap_export.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - when: (not __sap_install_media_detect_sapnwas_abap_export_extracted_stat.stat.exists) or - ( __sap_install_media_detect_sapnwas_abap_export_extracted_stat.stat.exists and not - sap_install_media_detect_skip_extraction_if_target_dir_exists) - -# Reason for noqa: Difficult to determine the change status in the shell command sequence -- name: SAP Install Media Detect - SAP NetWeaver AS (ABAP) platform only EXPORT - Find self-extracting RAR EXE (parent RAR file) and extract SAP NetWeaver (ABAP) Installation Export files # noqa no-changed-when - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'RAR self-extracting archive')" ]; then eval "{{ sap_install_media_detect_rar_extract }}" "{{ item }}{{ sap_install_media_detect_rar_extract_argument }}" sapnwas_abap_export_extracted/ ; fi - with_items: - - "{{ detect_directory_files_nwas_abap_export.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - when: (not __sap_install_media_detect_sapnwas_abap_export_extracted_stat.stat.exists) or - ( __sap_install_media_detect_sapnwas_abap_export_extracted_stat.stat.exists and not - sap_install_media_detect_skip_extraction_if_target_dir_exists) - -- name: SAP Install Media Detect - SAP NetWeaver AS (ABAP) platform only EXPORT - Identify EXPORT extracted - ansible.builtin.find: - paths: "{{ __sap_install_media_detect_software_main_directory }}/sapnwas_abap_export_extracted" - recurse: true - file_type: directory - patterns: '.*DATA_UNITS.*' - use_regex: true - register: detect_directory_export_extracted - -- name: SAP Install Media Detect - SAP NetWeaver AS (ABAP) platform only EXPORT - Local Directory source - re-list files in directory - ansible.builtin.command: find . -maxdepth 1 -type f - register: detect_directory_files - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - changed_when: false - when: - - sap_install_media_detect_source == "local_dir" - -- name: SAP Install Media Detect - SAP NetWeaver AS (ABAP) platform only EXPORT - Local Directory source - re-detect ZIP files (including no file extensions), ignore errors - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then echo {{ item }}; fi - register: detect_directory_files_zip_repeated -# changed_when: "item.stdout | length > 0" - with_items: - - "{{ detect_directory_files.stdout_lines }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - ignore_errors: true - when: - - sap_install_media_detect_source == "local_dir" - -- name: SAP Install Media Detect - SAP NetWeaver AS (ABAP) platform only EXPORT - Local Directory source - re-detect RAR files (including no file extensions), ignore errors - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'RAR')" ]; then echo {{ item }}; fi - register: detect_directory_files_rar_repeated -# changed_when: "item.stdout | length > 0" - with_items: - - "{{ detect_directory_files.stdout_lines }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - ignore_errors: true - when: - - sap_install_media_detect_source == "local_dir" - -# Reason for noqa: grep -q with pipefail shell option returns 141 instead of 0 -- name: SAP Install Media Detect - SAP NetWeaver AS (ABAP) platform only EXPORT - Local Directory source - re-identify EXPORT files # noqa risky-shell-pipe - ansible.builtin.shell: | - if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then - if zipinfo -1 {{ item }} | grep -q 'DATA_UNITS/EXP'; then - echo '{{ item }}' - fi - elif [ ! -z "$(file {{ item }} | grep 'RAR')" ]; then - if eval "{{ sap_install_media_detect_rar_list }}" {{ item }} | grep -q 'DATA_UNITS/EXP'; then - echo '{{ item }}' - fi - fi - register: detect_directory_files_nwas_abap_export_repeated - changed_when: "item | length > 0" - with_items: - - "{{ detect_directory_files_zip_repeated.results | map(attribute='stdout') | select() }}" - - "{{ detect_directory_files_rar_repeated.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - when: - - sap_install_media_detect_source == "local_dir" - -- name: SAP Install Media Detect - SAP NetWeaver AS (ABAP) platform only EXPORT - Local Directory source - move EXPORT compressed archive files - ansible.builtin.command: mv "{{ __sap_install_media_detect_software_main_directory }}/{{ item }}" "{{ __sap_install_media_detect_software_main_directory }}/sapnwas_abap_export/{{ item }}" - with_items: - - "{{ detect_directory_files_nwas_abap_export_repeated.results | map(attribute='stdout') | select() }}" - when: - - sap_install_media_detect_source == "local_dir" diff --git a/roles/sap_install_media_detect/tasks/detect_export_sapnwas_java.yml b/roles/sap_install_media_detect/tasks/detect_export_sapnwas_java.yml deleted file mode 100644 index 141681a35..000000000 --- a/roles/sap_install_media_detect/tasks/detect_export_sapnwas_java.yml +++ /dev/null @@ -1,164 +0,0 @@ ---- - -- name: SAP Install Media Detect - SAP NetWeaver AS (JAVA) platform only EXPORT - Get info of directory 'sapnwas_java_export_extracted' - ansible.builtin.stat: - path: "{{ __sap_install_media_detect_software_main_directory }}/sapnwas_java_export_extracted/" - register: __sap_install_media_detect_sapnwas_java_export_extracted_stat - -- name: SAP Install Media Detect - SAP NetWeaver AS (JAVA) platform only EXPORT - Ensure directory 'sapnwas_java_export_extracted' is absent - ansible.builtin.file: - path: "{{ __sap_install_media_detect_software_main_directory }}/sapnwas_java_export_extracted/" - state: absent - when: - - not sap_install_media_detect_skip_extraction_if_target_dir_exists - -- name: SAP Install Media Detect - SAP NetWeaver AS (JAVA) platform only EXPORT - Create Directories - ansible.builtin.file: - path: "{{ item }}" - state: directory - mode: '0755' - owner: root - group: root - with_items: - - "{{ __sap_install_media_detect_software_main_directory }}/sapnwas_java_export/" - - "{{ __sap_install_media_detect_software_main_directory }}/sapnwas_java_export_extracted/" - -- name: SAP Install Media Detect - SAP NetWeaver AS (JAVA) platform only EXPORT - List files in directory - ansible.builtin.command: find . -maxdepth 1 -type f - register: detect_directory_files - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - changed_when: false - -- name: SAP Install Media Detect - SAP NetWeaver AS (JAVA) platform only EXPORT - Detect ZIP files (including no file extensions), ignore errors - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then echo {{ item }}; fi - register: detect_directory_files_zip - with_items: - - "{{ detect_directory_files.stdout_lines }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - ignore_errors: true - changed_when: false - -- name: SAP Install Media Detect - SAP NetWeaver AS (JAVA) platform only EXPORT - Detect RAR files (including no file extensions), ignore errors - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'RAR')" ]; then echo {{ item }}; fi - register: detect_directory_files_rar - with_items: - - "{{ detect_directory_files.stdout_lines }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - ignore_errors: true - changed_when: false - -# Reason for noqa: grep -q with pipefail shell option returns 141 instead of 0 -- name: SAP Install Media Detect - SAP NetWeaver AS (JAVA) platform only EXPORT - Identify EXPORT files # noqa risky-shell-pipe - ansible.builtin.shell: | - if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then - if zipinfo -1 {{ item }} | grep -q 'DATA_UNITS/JAVA_EXPORT_JDMP'; then - echo '{{ item }}' - fi - elif [ ! -z "$(file {{ item }} | grep 'RAR')" ]; then - if eval "{{ sap_install_media_detect_rar_list }}" {{ item }} | grep -q 'DATA_UNITS/JAVA_EXPORT_JDMP'; then - echo '{{ item }}' - fi - fi - register: detect_directory_files_nwas_java_export - changed_when: "item | length > 0" - with_items: - - "{{ detect_directory_files_zip.results | map(attribute='stdout') | select() }}" - - "{{ detect_directory_files_rar.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - -# Reason for noqa: Difficult to determine the change status in the shell command sequence -- name: SAP Install Media Detect - SAP NetWeaver AS (JAVA) platform only EXPORT - If any ZIP, then extract the SAP NetWeaver (JAVA) Installation Export file (unzip) # noqa no-changed-when - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then unzip {{ item }} -d ./sapnwas_java_export_extracted ; fi - with_items: - - "{{ detect_directory_files_nwas_java_export.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - when: (not __sap_install_media_detect_sapnwas_java_export_extracted_stat.stat.exists) or - ( __sap_install_media_detect_sapnwas_java_export_extracted_stat.stat.exists and not - sap_install_media_detect_skip_extraction_if_target_dir_exists) - -# Reason for noqa: Difficult to determine the change status in the shell command sequence -- name: SAP Install Media Detect - SAP NetWeaver AS (JAVA) platform only EXPORT - Find self-extracting RAR EXE (parent RAR file) and extract SAP NetWeaver (JAVA) Installation Export files # noqa no-changed-when - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'RAR self-extracting archive')" ]; then eval "{{ sap_install_media_detect_rar_extract }}" "{{ item }}{{ sap_install_media_detect_rar_extract_argument }}" sapnwas_java_export_extracted/ ; fi - with_items: - - "{{ detect_directory_files_nwas_java_export.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - when: (not __sap_install_media_detect_sapnwas_java_export_extracted_stat.stat.exists) or - ( __sap_install_media_detect_sapnwas_java_export_extracted_stat.stat.exists and not - sap_install_media_detect_skip_extraction_if_target_dir_exists) - -- name: SAP Install Media Detect - SAP NetWeaver AS (JAVA) platform only EXPORT - Identify EXPORT extracted - ansible.builtin.find: - paths: "{{ __sap_install_media_detect_software_main_directory }}/sapnwas_java_export_extracted" - recurse: true - file_type: directory - patterns: '.*DATA_UNITS.*' - use_regex: true - register: detect_directory_export_extracted - -- name: SAP Install Media Detect - SAP NetWeaver AS (JAVA) platform only EXPORT - Local Directory source - re-list files in directory - ansible.builtin.command: find . -maxdepth 1 -type f - register: detect_directory_files - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - changed_when: false - when: - - sap_install_media_detect_source == "local_dir" - -- name: SAP Install Media Detect - SAP NetWeaver AS (JAVA) platform only EXPORT - Local Directory source - re-detect ZIP files (including no file extensions), ignore errors - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then echo {{ item }}; fi - register: detect_directory_files_zip_repeated -# changed_when: "item.stdout | length > 0" - with_items: - - "{{ detect_directory_files.stdout_lines }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - ignore_errors: true - when: - - sap_install_media_detect_source == "local_dir" - -- name: SAP Install Media Detect - SAP NetWeaver AS (JAVA) platform only EXPORT - Local Directory source - re-detect RAR files (including no file extensions), ignore errors - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'RAR')" ]; then echo {{ item }}; fi - register: detect_directory_files_rar_repeated -# changed_when: "item.stdout | length > 0" - with_items: - - "{{ detect_directory_files.stdout_lines }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - ignore_errors: true - when: - - sap_install_media_detect_source == "local_dir" - -# Reason for noqa: grep -q with pipefail shell option returns 141 instead of 0 -- name: SAP Install Media Detect - SAP NetWeaver AS (JAVA) platform only EXPORT - Local Directory source - re-identify EXPORT files # noqa risky-shell-pipe - ansible.builtin.shell: | - if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then - if zipinfo -1 {{ item }} | grep -q 'DATA_UNITS/JAVA_EXPORT_JDMP'; then - echo '{{ item }}' - fi - elif [ ! -z "$(file {{ item }} | grep 'RAR')" ]; then - if eval "{{ sap_install_media_detect_rar_list }}" {{ item }} | grep -q 'DATA_UNITS/JAVA_EXPORT_JDMP'; then - echo '{{ item }}' - fi - fi - register: detect_directory_files_nwas_java_export_repeated - changed_when: "item | length > 0" - with_items: - - "{{ detect_directory_files_zip_repeated.results | map(attribute='stdout') | select() }}" - - "{{ detect_directory_files_rar_repeated.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - when: - - sap_install_media_detect_source == "local_dir" - -- name: SAP Install Media Detect - SAP NetWeaver AS (JAVA) platform only EXPORT - Local Directory source - move EXPORT compressed archive files - ansible.builtin.command: mv "{{ __sap_install_media_detect_software_main_directory }}/{{ item }}" "{{ __sap_install_media_detect_software_main_directory }}/sapnwas_java_export/{{ item }}" - with_items: - - "{{ detect_directory_files_nwas_java_export_repeated.results | map(attribute='stdout') | select() }}" - when: - - sap_install_media_detect_source == "local_dir" diff --git a/roles/sap_install_media_detect/tasks/detect_export_saps4hana.yml b/roles/sap_install_media_detect/tasks/detect_export_saps4hana.yml deleted file mode 100644 index a427327bc..000000000 --- a/roles/sap_install_media_detect/tasks/detect_export_saps4hana.yml +++ /dev/null @@ -1,26 +0,0 @@ ---- - -- name: SAP Install Media Detect - SAP S/4HANA EXPORT - Create Directories - ansible.builtin.file: - path: "{{ item }}" - state: directory - mode: '0755' - owner: root - group: root - with_items: - - "{{ __sap_install_media_detect_software_main_directory }}/saps4hana_export/" - -- name: SAP Install Media Detect - SAP S/4HANA EXPORT - Identify SAP S/4HANA EXPORT files - ansible.builtin.find: - paths: "{{ __sap_install_media_detect_software_main_directory }}" - recurse: true - file_type: file - patterns: '.*S4.*EXPORT.*' - use_regex: true - register: s4hana_export_files - -- name: SAP Install Media Detect - SAP S/4HANA EXPORT - Local Directory source - move SAP S/4HANA EXPORT files - ansible.builtin.command: mv "{{ item.path }}" "{{ __sap_install_media_detect_software_main_directory }}/saps4hana_export/{{ item.path | basename }}" - with_items: "{{ s4hana_export_files.files }}" - when: - - sap_install_media_detect_source == "local_dir" diff --git a/roles/sap_install_media_detect/tasks/detect_export_sapsolman_abap.yml b/roles/sap_install_media_detect/tasks/detect_export_sapsolman_abap.yml deleted file mode 100644 index 7d88dae0d..000000000 --- a/roles/sap_install_media_detect/tasks/detect_export_sapsolman_abap.yml +++ /dev/null @@ -1,113 +0,0 @@ ---- - -- name: SAP Install Media Detect - SAP Solution Manager (ABAP) EXPORT - Get info of directory 'sapsolman_abap_export_extracted' - ansible.builtin.stat: - path: "{{ __sap_install_media_detect_software_main_directory }}/sapsolman_abap_export_extracted/" - register: __sap_install_media_detect_sapsolman_abap_export_extracted_stat - -- name: SAP Install Media Detect - SAP Solution Manager (ABAP) EXPORT - Ensure directory 'sapsolman_abap_export_extracted' is absent - ansible.builtin.file: - path: "{{ __sap_install_media_detect_software_main_directory }}/sapsolman_abap_export_extracted/" - state: absent - when: - - not sap_install_media_detect_skip_extraction_if_target_dir_exists - -- name: SAP Install Media Detect - SAP Solution Manager (ABAP) EXPORT - Create Directories - ansible.builtin.file: - path: "{{ item }}" - state: directory - mode: '0755' - owner: root - group: root - with_items: - - "{{ __sap_install_media_detect_software_main_directory }}/sapnwas_abap_export/" - - "{{ __sap_install_media_detect_software_main_directory }}/sapsolman_abap_export_extracted/" - -- name: SAP Install Media Detect - SAP Solution Manager (ABAP) EXPORT - List files in directory - ansible.builtin.command: find . -maxdepth 1 -type f - register: detect_directory_files - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - changed_when: false - -- name: SAP Install Media Detect - SAP Solution Manager (ABAP) EXPORT - Detect ZIP files (including no file extensions), ignore errors - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then echo {{ item }}; fi - register: detect_directory_files_zip - with_items: - - "{{ detect_directory_files.stdout_lines }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - ignore_errors: true - changed_when: false - -# Reason for noqa: grep -q with pipefail shell option returns 141 instead of 0 -- name: SAP Install Media Detect - SAP Solution Manager (ABAP) EXPORT - Identify EXPORT files # noqa risky-shell-pipe - ansible.builtin.shell: | - if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then if zipinfo -1 {{ item }} | grep -q 'DATA_UNITS/EXP' ; then echo '{{ item }}' ; fi ; fi - register: detect_directory_files_nwas_abap_export - changed_when: "item | length > 0" - with_items: - - "{{ detect_directory_files_zip.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - -# Reason for noqa: Difficult to determine the change status in the shell command sequence -- name: SAP Install Media Detect - SAP Solution Manager (ABAP) EXPORT - If any ZIP, then extract the SAP NetWeaver (ABAP) Installation Export file (unzip) # noqa no-changed-when - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then unzip {{ item }} -d ./sapsolman_abap_export_extracted/{{ item }} ; fi - with_items: - - "{{ detect_directory_files_nwas_abap_export.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - when: (not __sap_install_media_detect_sapsolman_abap_export_extracted_stat.stat.exists) or - ( __sap_install_media_detect_sapsolman_abap_export_extracted_stat.stat.exists and not - sap_install_media_detect_skip_extraction_if_target_dir_exists) - -- name: SAP Install Media Detect - SAP Solution Manager (ABAP) EXPORT - Identify EXPORT extracted - ansible.builtin.find: - paths: "{{ __sap_install_media_detect_software_main_directory }}/sapsolman_abap_export_extracted" - recurse: true - file_type: directory - patterns: '.*DATA_UNITS.*' - use_regex: true - register: detect_directory_export_extracted - -- name: SAP Install Media Detect - SAP Solution Manager (ABAP) EXPORT - Local Directory source - re-list files in directory - ansible.builtin.command: find . -maxdepth 1 -type f - register: detect_directory_files - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - changed_when: false - when: - - sap_install_media_detect_source == "local_dir" - -- name: SAP Install Media Detect - SAP Solution Manager (ABAP) EXPORT - Local Directory source - re-detect ZIP files (including no file extensions), ignore errors - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then echo {{ item }}; fi - register: detect_directory_files_zip_repeated -# changed_when: "item.stdout | length > 0" - with_items: - - "{{ detect_directory_files.stdout_lines }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - ignore_errors: true - when: - - sap_install_media_detect_source == "local_dir" - -# Reason for noqa: grep -q with pipefail shell option returns 141 instead of 0 -- name: SAP Install Media Detect - SAP Solution Manager (ABAP) EXPORT - Local Directory source - re-identify EXPORT files # noqa risky-shell-pipe - ansible.builtin.shell: | - if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then if zipinfo -1 {{ item }} | grep -q 'DATA_UNITS/EXP' ; then echo '{{ item }}' ; fi ; fi - register: detect_directory_files_nwas_abap_export_repeated - changed_when: "item | length > 0" - with_items: - - "{{ detect_directory_files_zip_repeated.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - when: - - sap_install_media_detect_source == "local_dir" - -- name: SAP Install Media Detect - SAP Solution Manager (ABAP) EXPORT - Local Directory source - move EXPORT compressed archive files - ansible.builtin.command: mv "{{ __sap_install_media_detect_software_main_directory }}/{{ item }}" "{{ __sap_install_media_detect_software_main_directory }}/sapnwas_abap_export/{{ item }}" - with_items: - - "{{ detect_directory_files_nwas_abap_export_repeated.results | map(attribute='stdout') | select() }}" - when: - - sap_install_media_detect_source == "local_dir" diff --git a/roles/sap_install_media_detect/tasks/detect_sapanydb_ibmdb2.yml b/roles/sap_install_media_detect/tasks/detect_sapanydb_ibmdb2.yml deleted file mode 100644 index 3f5d54fe1..000000000 --- a/roles/sap_install_media_detect/tasks/detect_sapanydb_ibmdb2.yml +++ /dev/null @@ -1,160 +0,0 @@ ---- - -- name: SAP Install Media Detect - IBM Db2 - Get info of directory 'ibmdb2_extracted' - ansible.builtin.stat: - path: "{{ __sap_install_media_detect_software_main_directory }}/ibmdb2_extracted/" - register: __sap_install_media_detect_ibmdb2_extracted_stat - -- name: SAP Install Media Detect - IBM Db2 - Ensure directory 'ibmdb2_extracted' is absent - ansible.builtin.file: - path: "{{ __sap_install_media_detect_software_main_directory }}/ibmdb2_extracted/" - state: absent - when: - - not sap_install_media_detect_skip_extraction_if_target_dir_exists - -- name: SAP Install Media Detect - IBM Db2 - Get info of directory 'ibmdb2_client_extracted' - ansible.builtin.stat: - path: "{{ __sap_install_media_detect_software_main_directory }}/ibmdb2_client_extracted/" - register: __sap_install_media_detect_ibmdb2_client_extracted_stat - -- name: SAP Install Media Detect - IBM Db2 - Ensure directory 'ibmdb2_client_extracted' is absent - ansible.builtin.file: - path: "{{ __sap_install_media_detect_software_main_directory }}/ibmdb2_client_extracted/" - state: absent - when: - - not sap_install_media_detect_skip_extraction_if_target_dir_exists - -- name: SAP Install Media Detect - IBM Db2 - Get info of directory 'ibmdb2_license_extracted' - ansible.builtin.stat: - path: "{{ __sap_install_media_detect_software_main_directory }}/ibmdb2_license_extracted/" - register: __sap_install_media_detect_ibmdb2_license_extracted_stat - -- name: SAP Install Media Detect - IBM Db2 - Ensure directory 'ibmdb2_license_extracted' is absent - ansible.builtin.file: - path: "{{ __sap_install_media_detect_software_main_directory }}/ibmdb2_license_extracted/" - state: absent - when: - - not sap_install_media_detect_skip_extraction_if_target_dir_exists - -- name: SAP Install Media Detect - IBM Db2 - Create Directories - ansible.builtin.file: - path: "{{ item }}" - state: directory - mode: '0755' - owner: root - group: root - with_items: - - "{{ __sap_install_media_detect_software_main_directory }}/ibmdb2/" - - "{{ __sap_install_media_detect_software_main_directory }}/ibmdb2_extracted/" - - "{{ __sap_install_media_detect_software_main_directory }}/ibmdb2_client_extracted/" - - "{{ __sap_install_media_detect_software_main_directory }}/ibmdb2_license_extracted/" - -- name: SAP Install Media Detect - IBM Db2 - List files in directory - ansible.builtin.command: find . -maxdepth 1 -type f - register: detect_directory_files - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - changed_when: false - -- name: SAP Install Media Detect - IBM Db2 - Detect ZIP files (including no file extensions), ignore errors - ansible.builtin.shell: if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then echo {{ item }}; fi - register: detect_directory_files_zip - with_items: - - "{{ detect_directory_files.stdout_lines }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - ignore_errors: true - changed_when: false - -# Reason for noqa: grep -q with pipefail shell option returns 141 instead of 0 -- name: SAP Install Media Detect - IBM Db2 - Identify IBM Db2 installation media # noqa risky-shell-pipe - ansible.builtin.shell: | - if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then if zipinfo -1 {{ item }} | grep -q 'db2setup' ; then echo '{{ item }}' ; fi ; fi - register: detect_directory_files_ibmdb2 - changed_when: "item | length > 0" - with_items: - - "{{ detect_directory_files_zip.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - -# Reason for noqa: grep -q with pipefail shell option returns 141 instead of 0 -- name: SAP Install Media Detect - IBM Db2 - Identify IBM Db2 Client installation media # noqa risky-shell-pipe - ansible.builtin.shell: | - if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then if zipinfo -1 {{ item }} | grep -q 'db6_update_client.sh' ; then echo '{{ item }}' ; fi ; fi - register: detect_directory_files_ibmdb2_client - changed_when: "item | length > 0" - with_items: - - "{{ detect_directory_files_zip.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - -# Reason for noqa: grep -q with pipefail shell option returns 141 instead of 0 -- name: SAP Install Media Detect - IBM Db2 - Identify IBM Db2 OEM license file # noqa risky-shell-pipe - ansible.builtin.shell: | - if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then if zipinfo -1 {{ item }} | grep -q 'db2aese_c.lic' ; then echo '{{ item }}' ; fi ; fi - register: detect_directory_files_ibmdb2_license - changed_when: "item | length > 0" - with_items: - - "{{ detect_directory_files_zip.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - -# Reason for noqa: Difficult to determine the change status in the shell command sequence -- name: SAP Install Media Detect - IBM Db2 - Extract ZIP files of IBM DB2 installation media # noqa no-changed-when - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then unzip {{ item }} -d {{ __sap_install_media_detect_software_main_directory }}/ibmdb2_extracted/{{ item }}_extracted; fi - with_items: - - "{{ detect_directory_files_ibmdb2.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - when: (not __sap_install_media_detect_ibmdb2_extracted_stat.stat.exists) or - ( __sap_install_media_detect_ibmdb2_extracted_stat.stat.exists and not - sap_install_media_detect_skip_extraction_if_target_dir_exists) - -# Reason for noqa: Difficult to determine the change status in the shell command sequence -- name: SAP Install Media Detect - IBM Db2 - Extract ZIP files of IBM DB2 Client installation media # noqa no-changed-when - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then unzip {{ item }} -d {{ __sap_install_media_detect_software_main_directory }}/ibmdb2_client_extracted/{{ item }}_extracted; fi - with_items: - - "{{ detect_directory_files_ibmdb2_client.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - when: (not __sap_install_media_detect_ibmdb2_client_extracted_stat.stat.exists) or - ( __sap_install_media_detect_ibmdb2_client_extracted_stat.stat.exists and not - sap_install_media_detect_skip_extraction_if_target_dir_exists) - -# Reason for noqa: Difficult to determine the change status in the shell command sequence -- name: SAP Install Media Detect - IBM Db2 - Extract ZIP files of IBM DB2 OEM license file # noqa no-changed-when - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then unzip {{ item }} -d {{ __sap_install_media_detect_software_main_directory }}/ibmdb2_license_extracted/{{ item }}_extracted; fi - with_items: - - "{{ detect_directory_files_ibmdb2_license.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - when: (not __sap_install_media_detect_ibmdb2_license_extracted_stat.stat.exists) or - ( __sap_install_media_detect_ibmdb2_license_extracted_stat.stat.exists and not - sap_install_media_detect_skip_extraction_if_target_dir_exists) - -- name: SAP Install Media Detect - IBM Db2 - Identify IBM Db2 extracted - ansible.builtin.find: - paths: "{{ __sap_install_media_detect_software_main_directory }}/ibmdb2_extracted" - recurse: true - file_type: directory - patterns: ".*LINUXX86_64.*" - use_regex: true - register: detect_directory_ibmdb2_extracted - -- name: SAP Install Media Detect - IBM Db2 - Identify IBM Db2 Client extracted - ansible.builtin.find: - paths: "{{ __sap_install_media_detect_software_main_directory }}/ibmdb2_client_extracted" - recurse: true - file_type: directory - patterns: ".*DATA_UNITS.*" - use_regex: true - register: detect_directory_ibmdb2_client_extracted - -- name: SAP Install Media Detect - IBM Db2 - Local Directory source - move IBM Db2 compressed archive files - ansible.builtin.command: mv "{{ __sap_install_media_detect_software_main_directory }}/{{ item }}" "{{ __sap_install_media_detect_software_main_directory }}/ibmdb2/{{ item }}" - with_items: - - "{{ detect_directory_files_ibmdb2.results | map(attribute='stdout') | select() }}" - - "{{ detect_directory_files_ibmdb2_client.results | map(attribute='stdout') | select() }}" - - "{{ detect_directory_files_ibmdb2_license.results | map(attribute='stdout') | select() }}" - when: - - sap_install_media_detect_source == "local_dir" diff --git a/roles/sap_install_media_detect/tasks/detect_sapanydb_oracledb.yml b/roles/sap_install_media_detect/tasks/detect_sapanydb_oracledb.yml deleted file mode 100644 index 55ace690f..000000000 --- a/roles/sap_install_media_detect/tasks/detect_sapanydb_oracledb.yml +++ /dev/null @@ -1,124 +0,0 @@ ---- - -- name: SAP Install Media Detect - Oracle DB - Get info of directory 'oracledb_extracted' - ansible.builtin.stat: - path: "{{ __sap_install_media_detect_software_main_directory }}/oracledb_extracted/" - register: __sap_install_media_detect_oracledb_extracted_stat - -- name: SAP Install Media Detect - Oracle DB - Ensure directory 'oracledb_extracted' is absent - ansible.builtin.file: - path: "{{ __sap_install_media_detect_software_main_directory }}/oracledb_extracted/" - state: absent - when: - - not sap_install_media_detect_skip_extraction_if_target_dir_exists - -- name: SAP Install Media Detect - Oracle DB - Get info of directory 'oracledb_client_extracted' - ansible.builtin.stat: - path: "{{ __sap_install_media_detect_software_main_directory }}/oracledb_client_extracted/" - register: __sap_install_media_detect_oracledb_client_extracted_stat - -- name: SAP Install Media Detect - Oracle DB - Ensure directory 'oracledb_client_extracted' is absent - ansible.builtin.file: - path: "{{ __sap_install_media_detect_software_main_directory }}/oracledb_client_extracted/" - state: absent - when: - - not sap_install_media_detect_skip_extraction_if_target_dir_exists - -- name: SAP Install Media Detect - Oracle DB - Create Directories - ansible.builtin.file: - path: "{{ item }}" - state: directory - mode: '0755' - owner: root - group: root - with_items: - - "{{ __sap_install_media_detect_software_main_directory }}/oracledb/" - - "{{ __sap_install_media_detect_software_main_directory }}/oracledb_extracted/" - - "{{ __sap_install_media_detect_software_main_directory }}/oracledb_client_extracted/" - -- name: SAP Install Media Detect - Oracle DB - List files in directory - ansible.builtin.command: find . -maxdepth 1 -type f - register: detect_directory_files - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - changed_when: false - -- name: SAP Install Media Detect - Oracle DB - Detect ZIP files (including no file extensions), ignore errors - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then echo {{ item }}; fi - register: detect_directory_files_zip - with_items: - - "{{ detect_directory_files.stdout_lines }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - ignore_errors: true - changed_when: false - -# Reason for noqa: grep -q with pipefail shell option returns 141 instead of 0 -- name: SAP Install Media Detect - Oracle DB - Identify Oracle DB installation media # noqa risky-shell-pipe - ansible.builtin.shell: | - if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then if zipinfo -1 {{ item }} | grep -q '19cinstall.sh' ; then echo '{{ item }}' ; fi ; fi - register: detect_directory_files_oracledb - changed_when: "item | length > 0" - with_items: - - "{{ detect_directory_files_zip.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - -# Reason for noqa: grep -q with pipefail shell option returns 141 instead of 0 -- name: SAP Install Media Detect - Oracle DB - Identify Oracle DB Client installation media # noqa risky-shell-pipe - ansible.builtin.shell: | - if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then if zipinfo -1 {{ item }} | grep -q 'OCL_LINUX_X86_64' ; then echo '{{ item }}' ; fi ; fi - register: detect_directory_files_oracledb_client - changed_when: "item | length > 0" - with_items: - - "{{ detect_directory_files_zip.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - -# Reason for noqa: Difficult to determine the change status in the shell command sequence -- name: SAP Install Media Detect - Oracle DB - Extract ZIP files of Oracle DB installation media # noqa no-changed-when - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then unzip {{ item }} -d {{ __sap_install_media_detect_software_main_directory }}/oracledb_extracted/{{ item }}_extracted; fi - with_items: - - "{{ detect_directory_files_oracledb.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - when: (not __sap_install_media_detect_oracledb_extracted_stat.stat.exists) or - ( __sap_install_media_detect_oracledb_extracted_stat.stat.exists and not - sap_install_media_detect_skip_extraction_if_target_dir_exists) - -# Reason for noqa: Difficult to determine the change status in the shell command sequence -- name: SAP Install Media Detect - Oracle DB - Extract ZIP files of Oracle DB Client installation media # noqa no-changed-when - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then unzip {{ item }} -d {{ __sap_install_media_detect_software_main_directory }}/oracledb_client_extracted/{{ item }}_extracted; fi - with_items: - - "{{ detect_directory_files_oracledb_client.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - when: (not __sap_install_media_detect_oracledb_client_extracted_stat.stat.exists) or - ( __sap_install_media_detect_oracledb_client_extracted_stat.stat.exists and not - sap_install_media_detect_skip_extraction_if_target_dir_exists) - -- name: SAP Install Media Detect - Oracle DB - Identify Oracle DB extracted - ansible.builtin.find: - paths: "{{ __sap_install_media_detect_software_main_directory }}/oracledb_extracted" - recurse: true - file_type: directory - patterns: ".*LINUX_X86_64.*" - use_regex: true - register: detect_directory_oracledb_extracted - -- name: SAP Install Media Detect - Oracle DB - Identify Oracle DB Client extracted - ansible.builtin.find: - paths: "{{ __sap_install_media_detect_software_main_directory }}/oracledb_client_extracted" - recurse: true - file_type: directory - patterns: ".*OCL_LINUX_X86_64.*" - use_regex: true - register: detect_directory_oracledb_client_extracted - -- name: SAP Install Media Detect - Oracle DB - Local Directory source - move Oracle DB compressed archive files - ansible.builtin.command: mv "{{ __sap_install_media_detect_software_main_directory }}/{{ item }}" "{{ __sap_install_media_detect_software_main_directory }}/oracledb/{{ item }}" - with_items: - - "{{ detect_directory_files_oracledb.results | map(attribute='stdout') | select() }}" - - "{{ detect_directory_files_oracledb_client.results | map(attribute='stdout') | select() }}" - when: - - sap_install_media_detect_source == "local_dir" diff --git a/roles/sap_install_media_detect/tasks/detect_sapanydb_sapase.yml b/roles/sap_install_media_detect/tasks/detect_sapanydb_sapase.yml deleted file mode 100644 index 7ffb0825c..000000000 --- a/roles/sap_install_media_detect/tasks/detect_sapanydb_sapase.yml +++ /dev/null @@ -1,110 +0,0 @@ ---- - -- name: SAP Install Media Detect - SAP ASE - Get info of directory 'sapase_extracted' - ansible.builtin.stat: - path: "{{ __sap_install_media_detect_software_main_directory }}/sapase_extracted/" - register: __sap_install_media_detect_sapase_extracted_stat - -- name: SAP Install Media Detect - SAP ASE - Ensure directory 'sapase_extracted' is absent - ansible.builtin.file: - path: "{{ __sap_install_media_detect_software_main_directory }}/sapase_extracted/" - state: absent - when: - - not sap_install_media_detect_skip_extraction_if_target_dir_exists - -- name: SAP Install Media Detect - SAP ASE - Create Directories - ansible.builtin.file: - path: "{{ item }}" - state: directory - mode: '0755' - owner: root - group: root - with_items: - - "{{ __sap_install_media_detect_software_main_directory }}/sapase/" - - "{{ __sap_install_media_detect_software_main_directory }}/sapase_extracted/" - - "{{ __sap_install_media_detect_software_main_directory }}/sapase_client_extracted/" - -- name: SAP Install Media Detect - SAP ASE - List files in directory - ansible.builtin.command: find . -maxdepth 1 -type f - register: detect_directory_files - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - changed_when: false - -- name: SAP Install Media Detect - SAP ASE - Detect ZIP files (including no file extensions), ignore errors - ansible.builtin.shell: if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then echo {{ item }}; fi - register: detect_directory_files_zip - with_items: - - "{{ detect_directory_files.stdout_lines }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - ignore_errors: true - changed_when: false - -# Reason for noqa: grep -q with pipefail shell option returns 141 instead of 0 -- name: SAP Install Media Detect - SAP ASE - Identify SAP ASE installation media # noqa risky-shell-pipe - ansible.builtin.shell: | - if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then if zipinfo -1 {{ item }} | grep -q 'BD_SYBASE_ASE' ; then echo '{{ item }}' ; fi ; fi - register: detect_directory_files_sapase - changed_when: "item | length > 0" - with_items: - - "{{ detect_directory_files_zip.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - -- name: SAP Install Media Detect - SAP ASE - Identify SAP ASE Client installation media - ansible.builtin.find: - paths: "{{ __sap_install_media_detect_software_main_directory }}" - recurse: true - file_type: file - patterns: '.*ASEBC.*' - use_regex: true - register: detect_directory_files_sapase_client - -# Reason for noqa: Difficult to determine the change status in the shell command sequence -- name: SAP Install Media Detect - SAP ASE - Extract ZIP files of SAP ASE installation media # noqa no-changed-when - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then unzip {{ item }} -d {{ __sap_install_media_detect_software_main_directory }}/sapase_extracted/{{ item }}_extracted; fi - with_items: - - "{{ detect_directory_files_sapase.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - when: (not __sap_install_media_detect_sapase_extracted_stat.stat.exists) or - ( __sap_install_media_detect_sapase_extracted_stat.stat.exists and not - sap_install_media_detect_skip_extraction_if_target_dir_exists) - -- name: SAP Install Media Detect - SAP ASE - Extract SAP ASE 16.0 Client with SAPCAR - ansible.builtin.shell: | - {{ __sap_install_media_detect_software_main_directory }}/{{ sap_swpm_sapcar_file_name }} \ - -xvf {{ item }} \ - -manifest SIGNATURE.SMF \ - -R "{{ __sap_install_media_detect_software_main_directory }}/sapase_client_extracted" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - with_items: - - "{{ detect_directory_files_sapase_client.files[0].path }}" - changed_when: true - -- name: SAP Install Media Detect - SAP ASE - Identify SAP ASE extracted - ansible.builtin.find: - paths: "{{ __sap_install_media_detect_software_main_directory }}/sapase_extracted" - recurse: true - file_type: directory - patterns: ".*SYBASE_LINUX.*" - use_regex: true - register: detect_directory_sapase_extracted - -- name: SAP Install Media Detect - SAP ASE - Identify SAP ASE Client extracted - ansible.builtin.find: - paths: "{{ __sap_install_media_detect_software_main_directory }}/sapase_client_extracted" - recurse: true - file_type: file - patterns: ".*sybodbc.*" - use_regex: true - register: detect_directory_sapase_client_extracted - -- name: SAP Install Media Detect - SAP ASE - Local Directory source - move SAP ASE compressed archive files - ansible.builtin.command: mv "{{ __sap_install_media_detect_software_main_directory }}/{{ item }}" "{{ __sap_install_media_detect_software_main_directory }}/sapase/{{ item }}" - with_items: - - "{{ detect_directory_files_sapase.results | map(attribute='stdout') | select() }}" - when: - - sap_install_media_detect_source == "local_dir" diff --git a/roles/sap_install_media_detect/tasks/detect_sapanydb_sapmaxdb.yml b/roles/sap_install_media_detect/tasks/detect_sapanydb_sapmaxdb.yml deleted file mode 100644 index ec70a2190..000000000 --- a/roles/sap_install_media_detect/tasks/detect_sapanydb_sapmaxdb.yml +++ /dev/null @@ -1,79 +0,0 @@ ---- - -- name: SAP Install Media Detect - SAP MaxDB - Get info of directory 'sapmaxdb_extracted' - ansible.builtin.stat: - path: "{{ __sap_install_media_detect_software_main_directory }}/sapmaxdb_extracted/" - register: __sap_install_media_detect_sapmaxdb_extracted_stat - -- name: SAP Install Media Detect - SAP MaxDB - Ensure directory 'sapmaxdb_extracted' is absent - ansible.builtin.file: - path: "{{ __sap_install_media_detect_software_main_directory }}/sapmaxdb_extracted/" - state: absent - when: - - not sap_install_media_detect_skip_extraction_if_target_dir_exists - -- name: SAP Install Media Detect - SAP MaxDB - Create Directories - ansible.builtin.file: - path: "{{ item }}" - state: directory - mode: '0755' - owner: root - group: root - with_items: - - "{{ __sap_install_media_detect_software_main_directory }}/sapmaxdb/" - - "{{ __sap_install_media_detect_software_main_directory }}/sapmaxdb_extracted/" - -- name: SAP Install Media Detect - SAP MaxDB - List files in directory - ansible.builtin.command: find . -maxdepth 1 -type f - register: detect_directory_files - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - changed_when: false - -- name: SAP Install Media Detect - SAP MaxDB - Detect ZIP files (including no file extensions), ignore errors - ansible.builtin.shell: if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then echo {{ item }}; fi - register: detect_directory_files_zip - with_items: - - "{{ detect_directory_files.stdout_lines }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - ignore_errors: true - changed_when: false - -# Reason for noqa: grep -q with pipefail shell option returns 141 instead of 0 -- name: SAP Install Media Detect - SAP MaxDB - Identify SAP MaxDB installation media # noqa risky-shell-pipe - ansible.builtin.shell: | - if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then if zipinfo -1 {{ item }} | grep -q 'MaxDB_7.9' ; then echo '{{ item }}' ; fi ; fi - register: detect_directory_files_sapmaxdb - changed_when: "item | length > 0" - with_items: - - "{{ detect_directory_files_zip.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - -# Reason for noqa: Difficult to determine the change status in the shell command sequence -- name: SAP Install Media Detect - SAP MaxDB - Extract ZIP files of SAP MaxDB installation media # noqa no-changed-when - ansible.builtin.shell: set -o pipefail && if [ ! -z "$(file {{ item }} | grep 'Zip archive data')" ]; then unzip {{ item }} -d {{ __sap_install_media_detect_software_main_directory }}/sapmaxdb_extracted/{{ item }}_extracted; fi - with_items: - - "{{ detect_directory_files_sapmaxdb.results | map(attribute='stdout') | select() }}" - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - when: (not __sap_install_media_detect_sapmaxdb_extracted_stat.stat.exists) or - ( __sap_install_media_detect_sapmaxdb_extracted_stat.stat.exists and not - sap_install_media_detect_skip_extraction_if_target_dir_exists) - -- name: SAP Install Media Detect - SAP MaxDB - Identify SAP MaxDB extracted - ansible.builtin.find: - paths: "{{ __sap_install_media_detect_software_main_directory }}/sapmaxdb_extracted/" - recurse: true - file_type: directory - patterns: '.*MaxDB_7.9.*' - use_regex: true - register: detect_directory_sapmaxdb_extracted - -- name: SAP Install Media Detect - SAP MaxDB - Local Directory source - move SAP MaxDB compressed archive files - ansible.builtin.command: mv "{{ __sap_install_media_detect_software_main_directory }}/{{ item }}" "{{ __sap_install_media_detect_software_main_directory }}/sapmaxdb/{{ item }}" - with_items: - - "{{ detect_directory_files_sapmaxdb.results | map(attribute='stdout') | select() }}" - when: - - sap_install_media_detect_source == "local_dir" diff --git a/roles/sap_install_media_detect/tasks/detect_sapcar.yml b/roles/sap_install_media_detect/tasks/detect_sapcar.yml deleted file mode 100644 index a994203f9..000000000 --- a/roles/sap_install_media_detect/tasks/detect_sapcar.yml +++ /dev/null @@ -1,20 +0,0 @@ ---- - -- name: SAP Install Media Detect - SAPCAR - Get SAPCAR executable file from folder - {{ __sap_install_media_detect_software_main_directory }} - ansible.builtin.shell: ls SAPCAR*.EXE - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - register: sap_swpm_sapcar_file_name_get - changed_when: false - -- name: SAP Install Media Detect - SAPCAR - Set fact - ansible.builtin.set_fact: - sap_swpm_sapcar_file_name: "{{ sap_swpm_sapcar_file_name_get.stdout }}" - -- name: SAP Install Media Detect - SAPCAR - Change ownership of SAPCAR - ansible.builtin.file: - path: "{{ __sap_install_media_detect_software_main_directory }}/{{ sap_swpm_sapcar_file_name }}" - state: file - mode: '0755' - owner: root - group: root diff --git a/roles/sap_install_media_detect/tasks/detect_saphana.yml b/roles/sap_install_media_detect/tasks/detect_saphana.yml deleted file mode 100644 index 0f54d24ad..000000000 --- a/roles/sap_install_media_detect/tasks/detect_saphana.yml +++ /dev/null @@ -1,124 +0,0 @@ ---- - -- name: SAP Install Media Detect - SAP HANA - Set fact for install media directory - ansible.builtin.set_fact: - sap_hana_install_directory: "{{ __sap_install_media_detect_software_main_directory }}/sap_hana" - -- name: SAP Install Media Detect - SAP HANA - Create Directory - {{ sap_hana_install_directory }} - ansible.builtin.file: - path: "{{ sap_hana_install_directory }}" - state: directory - mode: '0755' - owner: root - group: root - -- name: SAP Install Media Detect - SAP HANA - Copy SAPCAR file - ansible.builtin.shell: | - cp {{ __sap_install_media_detect_software_main_directory }}/{{ sap_swpm_sapcar_file_name_get.stdout }} {{ sap_hana_install_directory }}/{{ sap_swpm_sapcar_file_name_get.stdout }} - changed_when: true - -# IMDB SAR Files -- name: SAP Install Media Detect - SAP HANA - Get all IMDB SAR files in folder - {{ __sap_install_media_detect_software_main_directory }} - ansible.builtin.shell: ls IMDB*.SAR - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - register: imdb_sarfiles_list - changed_when: false - -- name: SAP Install Media Detect - SAP HANA - Set fact list of SAR files - ansible.builtin.set_fact: - sap_hana_install_imdb_sar: "{{ imdb_sarfiles_list.stdout.split() }}" - when: - - not( imdb_sarfiles_list.stdout == '' ) - -- name: SAP Install Media Detect - SAP HANA - Copy SAP HANA files - ansible.builtin.shell: | - cp {{ __sap_install_media_detect_software_main_directory }}/{{ item }} {{ __sap_install_media_detect_software_main_directory }}/sap_hana/{{ item }} - loop: "{{ sap_hana_install_imdb_sar }}" - when: - - not( imdb_sarfiles_list.stdout == '' ) - -- name: SAP Install Media Detect - SAP HANA - Check availability of software path - {{ sap_hana_install_directory }} - ansible.builtin.stat: - path: "{{ sap_hana_install_directory }}" - register: sap_hana_install_software_path_stat - failed_when: not sap_hana_install_software_path_stat.stat.exists - -- name: SAP Install Media Detect - SAP HANA - Change ownership of software path - {{ sap_hana_install_directory }} - ansible.builtin.file: - path: "{{ sap_hana_install_directory }}" - state: directory - recurse: yes - mode: '0755' - owner: root - group: root - -# Create directory {{ sap_hana_install_directory }}/extracted -# This is where all extracted .SAR files will be stored -- name: SAP Install Media Detect - SAP HANA - Remove directory - {{ sap_hana_install_directory }}/extracted - ansible.builtin.file: - path: "{{ sap_hana_install_directory }}/extracted" - state: absent - -- name: SAP Install Media Detect - SAP HANA - Create directory - {{ sap_hana_install_directory }}/extracted - ansible.builtin.file: - path: "{{ sap_hana_install_directory }}/extracted" - state: directory - mode: '0755' - -- name: SAP Install Media Detect - SAP HANA - Change ownership of deployment directory - {{ sap_hana_install_directory }} - ansible.builtin.file: - path: "{{ sap_hana_install_directory }}" - state: directory - recurse: yes - mode: '0755' - owner: root - group: root - -- name: SAP Install Media Detect - SAP HANA - Get all SAR files in folder - {{ sap_hana_install_directory }} - ansible.builtin.shell: ls *.SAR - args: - chdir: "{{ sap_hana_install_directory }}" - register: sarfiles_list - changed_when: false - -- name: SAP Install Media Detect - SAP HANA - Set fact for list of SAR files - ansible.builtin.set_fact: - sap_hana_install_components_sar: "{{ sarfiles_list.stdout.split() }}" - when: - - not( sarfiles_list.stdout == '' ) - -- name: SAP Install Media Detect - SAP HANA - Extract all SAR files in folder - {{ sap_hana_install_directory }} - ansible.builtin.include_tasks: ./extract/sapcar_loop_handler_saphana.yml - register: extract_all_sar_files - loop: "{{ sap_hana_install_components_sar }}" - loop_control: - loop_var: passed_sap_hana_install_components_sar - when: - - not( sarfiles_list.stdout == '' ) - -- name: SAP Install Media Detect - SAP HANA - Change ownership of software path - {{ sap_hana_install_directory }} - ansible.builtin.file: - path: "{{ sap_hana_install_directory }}" - state: directory - recurse: yes - mode: '0755' - owner: root - group: root - -- name: SAP Install Media Detect - SAP HANA - Find SAP_HANA_DATABASE - ansible.builtin.find: - paths: "{{ sap_hana_install_directory }}" - recurse: true - file_type: directory - patterns: "SAP_HANA_DATABASE" - register: sap_hana_database - -- name: SAP Install Media Detect - SAP HANA - Find SAP_HANA_CLIENT for SAP SWPM - ansible.builtin.find: - paths: "{{ sap_hana_install_directory }}" - recurse: true - file_type: directory - patterns: "SAP_HANA_CLIENT" - register: sap_hana_client_path - ignore_errors: true diff --git a/roles/sap_install_media_detect/tasks/detect_saphostagent.yml b/roles/sap_install_media_detect/tasks/detect_saphostagent.yml deleted file mode 100644 index b9d92b6d2..000000000 --- a/roles/sap_install_media_detect/tasks/detect_saphostagent.yml +++ /dev/null @@ -1,26 +0,0 @@ ---- - -- name: SAP Install Media Detect - SAP Host Agent - Set fact for install media directory - ansible.builtin.set_fact: - sap_hostagent_install_directory: "{{ __sap_install_media_detect_software_main_directory }}/sap_hostagent" - -- name: SAP Install Media Detect - SAP Host Agent - Create Directory - {{ sap_hostagent_install_directory }} - ansible.builtin.file: - path: "{{ sap_hostagent_install_directory }}" - state: directory - mode: '0755' - owner: root - group: root - -# SAPHOSTAGENT -- name: SAP Install Media Detect - SAP Host Agent - Get SAPHOSTAGENT SAR file from folder - {{ __sap_install_media_detect_software_main_directory }} - ansible.builtin.shell: ls SAPHOSTAGENT*SAR - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - register: saphostagent_sarfile - changed_when: false - -- name: SAP Install Media Detect - SAP Host Agent - Copy SAPHOSTAGENT SAR file - ansible.builtin.shell: | - cp {{ __sap_install_media_detect_software_main_directory }}/{{ saphostagent_sarfile.stdout }} {{ sap_hostagent_install_directory }}/{{ saphostagent_sarfile.stdout }} - changed_when: true diff --git a/roles/sap_install_media_detect/tasks/detect_sapigs.yml b/roles/sap_install_media_detect/tasks/detect_sapigs.yml deleted file mode 100644 index 9c08067f7..000000000 --- a/roles/sap_install_media_detect/tasks/detect_sapigs.yml +++ /dev/null @@ -1,39 +0,0 @@ ---- - -- name: SAP Install Media Detect - SAP IGS - Get IGS from software path - ansible.builtin.shell: ls igsexe*.sar - args: - chdir: "{{ sap_swpm_software_path }}" - register: sap_swpm_igs_file_name_get - changed_when: false - -- name: SAP Install Media Detect - SAP IGS - Set fact for IGS - ansible.builtin.set_fact: - sap_swpm_igs_path: "{{ sap_swpm_software_path }}" - sap_swpm_igs_file_name: "{{ sap_swpm_igs_file_name_get.stdout }}" - -# failed_when will trigger if more than 1 igsexe is identified and added to the register -- name: SAP Install Media Detect - SAP IGS - Check availability of IGS - {{ sap_swpm_igs_path }}/{{ sap_swpm_igs_file_name }} - ansible.builtin.stat: - path: "{{ sap_swpm_igs_path }}/{{ sap_swpm_igs_file_name }}" - register: sap_swpm_igs_file_name_stat - failed_when: not sap_swpm_igs_file_name_stat.stat.exists - -# 4. IGS Helper -- name: SAP Install Media Detect - SAP IGS - Get IGS Helper from software path - ansible.builtin.shell: ls igshelper*.sar - args: - chdir: "{{ sap_swpm_software_path }}" - register: sap_swpm_igs_helper_file_name_get - changed_when: false - -- name: SAP Install Media Detect - SAP IGS - Set fact for IGS - ansible.builtin.set_fact: - sap_swpm_igs_helper_path: "{{ sap_swpm_software_path }}" - sap_swpm_igs_helper_file_name: "{{ sap_swpm_igs_helper_file_name_get.stdout }}" - -- name: SAP Install Media Detect - SAP IGS - Check availability of IGS Helper - {{ sap_swpm_igs_helper_path }}/{{ sap_swpm_igs_helper_file_name }} - ansible.builtin.stat: - path: "{{ sap_swpm_igs_helper_path }}/{{ sap_swpm_igs_helper_file_name }}" - register: sap_swpm_igs_helper_file_name_stat - failed_when: not sap_swpm_igs_helper_file_name_stat.stat.exists diff --git a/roles/sap_install_media_detect/tasks/detect_sapkernel.yml b/roles/sap_install_media_detect/tasks/detect_sapkernel.yml deleted file mode 100644 index 911dd5a10..000000000 --- a/roles/sap_install_media_detect/tasks/detect_sapkernel.yml +++ /dev/null @@ -1,39 +0,0 @@ ---- - -# 5. SAPEXEDB -- name: SAP Install Media Detect - SAP Kernel - Get SAPEXEDB from software path - ansible.builtin.shell: ls SAPEXEDB_*.SAR - args: - chdir: "{{ sap_swpm_software_path }}" - register: sap_swpm_kernel_dependent_file_name_get - changed_when: false - -- name: SAP Install Media Detect - SAP Kernel - Set fact for SAPEXEDB - ansible.builtin.set_fact: - sap_swpm_kernel_dependent_path: "{{ sap_swpm_software_path }}" - sap_swpm_kernel_dependent_file_name: "{{ sap_swpm_kernel_dependent_file_name_get.stdout }}" - -- name: SAP Install Media Detect - SAP Kernel - Check availability of SAPEXEDB - {{ sap_swpm_kernel_dependent_path }}/{{ sap_swpm_kernel_dependent_file_name }} - ansible.builtin.stat: - path: "{{ sap_swpm_kernel_dependent_path }}/{{ sap_swpm_kernel_dependent_file_name }}" - register: sap_swpm_kernel_dependent_file_name_stat - failed_when: not sap_swpm_kernel_dependent_file_name_stat.stat.exists - -# 6. SAPEXE -- name: SAP Install Media Detect - SAP Kernel - Get SAPEXE from software path - ansible.builtin.shell: ls SAPEXE_*.SAR - args: - chdir: "{{ sap_swpm_software_path }}" - register: sap_swpm_kernel_independent_file_name_get - changed_when: false - -- name: SAP Install Media Detect - SAP Kernel - Set fact for SAPEXE - ansible.builtin.set_fact: - sap_swpm_kernel_independent_path: "{{ sap_swpm_software_path }}" - sap_swpm_kernel_independent_file_name: "{{ sap_swpm_kernel_independent_file_name_get.stdout }}" - -- name: SAP Install Media Detect - SAP Kernel - Check availability of SAPEXE - {{ sap_swpm_kernel_independent_path }}/{{ sap_swpm_kernel_independent_file_name }} - ansible.builtin.stat: - path: "{{ sap_swpm_kernel_independent_path }}/{{ sap_swpm_kernel_independent_file_name }}" - register: sap_swpm_kernel_independent_file_name_stat - failed_when: not sap_swpm_kernel_independent_file_name_stat.stat.exists diff --git a/roles/sap_install_media_detect/tasks/detect_sapswpm.yml b/roles/sap_install_media_detect/tasks/detect_sapswpm.yml deleted file mode 100644 index e42f0b963..000000000 --- a/roles/sap_install_media_detect/tasks/detect_sapswpm.yml +++ /dev/null @@ -1,123 +0,0 @@ ---- - -- name: SAP Install Media Detect - SAP SWPM - Set fact for install media directory - ansible.builtin.set_fact: - sap_swpm_install_directory: "{{ __sap_install_media_detect_software_main_directory }}/sap_swpm" - sap_swpm_software_path: "{{ __sap_install_media_detect_software_main_directory }}" - sap_swpm_swpm_path: "{{ __sap_install_media_detect_software_main_directory }}/sap_swpm" - -- name: SAP Install Media Detect - SAP SWPM - Create Directory - {{ sap_swpm_install_directory }} - ansible.builtin.file: - path: "{{ sap_swpm_install_directory }}" - state: directory - mode: '0755' - owner: root - group: root - -- name: SAP Install Media Detect - SAP SWPM - Copy SAPCAR file - ansible.builtin.shell: | - cp {{ __sap_install_media_detect_software_main_directory }}/{{ sap_swpm_sapcar_file_name_get.stdout }} {{ sap_swpm_install_directory }}/{{ sap_swpm_sapcar_file_name_get.stdout }} - changed_when: true - -# SWPM -- name: SAP Install Media Detect - SAP SWPM - Get SWPM from {{ __sap_install_media_detect_software_main_directory }} - ansible.builtin.shell: ls SWPM*.SAR - args: - chdir: "{{ __sap_install_media_detect_software_main_directory }}" - register: sap_swpm_swpm_sar_file_name_get - changed_when: false - -- name: SAP Install Media Detect - SAP SWPM - Copy SWPM file - ansible.builtin.shell: | - cp {{ __sap_install_media_detect_software_main_directory }}/{{ sap_swpm_swpm_sar_file_name_get.stdout }} {{ __sap_install_media_detect_software_main_directory }}/sap_swpm/{{ sap_swpm_swpm_sar_file_name_get.stdout }} - changed_when: true - - -- name: SAP Install Media Detect - SAP SWPM - Check availability of software path - {{ sap_swpm_software_path }} - ansible.builtin.stat: - path: "{{ sap_swpm_software_path }}" - register: sap_swpm_software_path_stat - failed_when: not sap_swpm_software_path_stat.stat.exists - -- name: SAP Install Media Detect - SAP SWPM - Change ownership of software path - {{ sap_swpm_software_path }} - ansible.builtin.file: - path: "{{ sap_swpm_software_path }}" - state: directory - recurse: yes - mode: '0755' - owner: root - group: root - - -################ -# Prepare software path -################ - -# Software Path - -# Backup Location - this is moved to install_type/restore_install.yml - -# - name: SAP SWPM Pre Install - Check backup location - -# block: - -# - name: SAP Install Media Detect - SAP SWPM - Check availability backup location - {{ sap_swpm_backup_location }} -# ansible.builtin.stat: -# path: "{{ sap_swpm_backup_location }}" -# register: sap_swpm_backup_location_stat -# failed_when: not sap_swpm_backup_location_stat.stat.exists and '.CP' in sap_swpm_product_catalog_id - -# - name: SAP Install Media Detect - SAP SWPM - Change ownership of backup location - {{ sap_swpm_backup_location }} -# ansible.builtin.file: -# path: "{{ sap_swpm_backup_location }}" -# state: directory -# recurse: yes -# mode: '0755' -# owner: root -# group: root -# when: -# - sap_swpm_backup_location_stat.stat.exists and sap_swpm_backup_location_stat.stat.isdir - -# when: -# - "'restore' in sap_swpm_swpm_installation_type" - -# SWPM Path - -- name: SAP Install Media Detect - SAP SWPM - Check availability of SWPM path - {{ sap_swpm_swpm_path }} - ansible.builtin.stat: - path: "{{ sap_swpm_swpm_path }}" - register: sap_swpm_swpm_path_stat - failed_when: not sap_swpm_swpm_path_stat.stat.exists - -- name: SAP Install Media Detect - SAP SWPM - Change ownership of SWPM path - {{ sap_swpm_swpm_path }} - ansible.builtin.file: - path: "{{ sap_swpm_swpm_path }}" - state: directory - recurse: yes - mode: '0755' - owner: root - group: root - - -################ -# Get software files from software paths -################ - -# 2. SWPM - -- name: SAP Install Media Detect - SAP SWPM - Get SWPM from {{ sap_swpm_swpm_path }} - ansible.builtin.shell: ls SWPM*.SAR - args: - chdir: "{{ sap_swpm_swpm_path }}" - register: sap_swpm_swpm_sar_file_name_get - changed_when: false - -- name: SAP Install Media Detect - SAP SWPM - Set fact for SWPM - ansible.builtin.set_fact: - sap_swpm_swpm_sar_file_name: "{{ sap_swpm_swpm_sar_file_name_get.stdout }}" - -- name: SAP Install Media Detect - SAP SWPM - Check availability of SWPM - {{ sap_swpm_swpm_path }}/{{ sap_swpm_swpm_sar_file_name }} - ansible.builtin.stat: - path: "{{ sap_swpm_swpm_path }}/{{ sap_swpm_swpm_sar_file_name }}" - register: sap_swpm_swpm_sar_file_name_stat - failed_when: not sap_swpm_swpm_sar_file_name_stat.stat.exists diff --git a/roles/sap_install_media_detect/tasks/detect_sapwebdisp.yml b/roles/sap_install_media_detect/tasks/detect_sapwebdisp.yml deleted file mode 100644 index 960f22cb6..000000000 --- a/roles/sap_install_media_detect/tasks/detect_sapwebdisp.yml +++ /dev/null @@ -1,23 +0,0 @@ ---- - -# 7. Web Dispatcher -- name: SAP Install Media Detect - SAP WebDisp - Get WEBDISP from software path - ansible.builtin.shell: ls SAPWEBDISP_*.SAR - args: - chdir: "{{ sap_swpm_software_path }}" - register: sap_swpm_web_dispatcher_file_name_get - ignore_errors: true - changed_when: false - -- name: SAP Install Media Detect - SAP WebDisp - Set fact for WEBDISP - ansible.builtin.set_fact: - sap_swpm_web_dispatcher_path: "{{ sap_swpm_software_path }}" - sap_swpm_web_dispatcher_file_name: "{{ sap_swpm_web_dispatcher_file_name_get.stdout }}" - ignore_errors: true - -- name: SAP Install Media Detect - SAP WebDisp - Check availability of WEBDISP - {{ sap_swpm_web_dispatcher_path }}/{{ sap_swpm_web_dispatcher_file_name }} - ansible.builtin.stat: - path: "{{ sap_swpm_web_dispatcher_path }}/{{ sap_swpm_web_dispatcher_file_name }}" - register: sap_swpm_web_dispatcher_file_name_stat - failed_when: not sap_swpm_web_dispatcher_file_name_stat.stat.exists - ignore_errors: true diff --git a/roles/sap_install_media_detect/tasks/extract/sapcar_loop_handler_saphana.yml b/roles/sap_install_media_detect/tasks/extract/sapcar_loop_handler_saphana.yml deleted file mode 100644 index b99da95da..000000000 --- a/roles/sap_install_media_detect/tasks/extract/sapcar_loop_handler_saphana.yml +++ /dev/null @@ -1,41 +0,0 @@ ---- - -- name: SAP Install Media Detect - SAP HANA - SAPCAR Extract Loop - Create temp dir - {{ sap_hana_install_directory }}/tmp - ansible.builtin.file: - path: "{{ sap_hana_install_directory }}/tmp" - state: directory - mode: '0700' - -- name: SAP Install Media Detect - SAP HANA - SAPCAR Extract Loop - Extracting {{ passed_sap_hana_install_components_sar }} - ansible.builtin.command: >- - {{ sap_hana_install_directory }}/{{ sap_swpm_sapcar_file_name_get.stdout }} \ - -R {{ sap_hana_install_directory }}/tmp - -xvf {{ sap_hana_install_directory }}/{{ passed_sap_hana_install_components_sar }} \ - -manifest SIGNATURE.SMF - register: sap_hana_install_extract - args: - chdir: "{{ sap_hana_install_directory }}" - changed_when: "'SAPCAR: processing archive' in sap_hana_install_extract.stdout" - -- name: SAP Install Media Detect - SAP HANA - SAPCAR Extract Loop - Create directory if SAP Host Agent - ansible.builtin.file: - path: "{{ sap_hana_install_directory }}/tmp/SAP_HOST_AGENT" - state: directory - mode: '0755' - owner: root - group: root - when: "'SAPHOST' in passed_sap_hana_install_components_sar" - -- name: SAP Install Media Detect - SAP HANA - SAPCAR Extract Loop - Prepare extracted dir - ansible.builtin.shell: | - extracted_dir=$(ls -d */) - cp SIGNATURE.SMF $extracted_dir - cp -R $extracted_dir ../extracted/$extracted_dir - args: - chdir: "{{ sap_hana_install_directory }}/tmp" - changed_when: true - -- name: SAP Install Media Detect - SAP HANA - SAPCAR Extract Loop - Remove temp dir - {{ sap_hana_install_directory }}/tmp - ansible.builtin.file: - path: "{{ sap_hana_install_directory }}/tmp" - state: absent diff --git a/roles/sap_install_media_detect/tasks/find_files_after_extraction.yml b/roles/sap_install_media_detect/tasks/find_files_after_extraction.yml new file mode 100644 index 000000000..fcf0ccbd7 --- /dev/null +++ b/roles/sap_install_media_detect/tasks/find_files_after_extraction.yml @@ -0,0 +1,358 @@ +--- + +- name: SAP Install Media Detect - Find files after extraction - Initialize fact variables + ansible.builtin.set_fact: + __sap_install_media_detect_fact_db_dependent_kernel_files_sapfile_results: [] + +- name: SAP Install Media Detect - Find files after extraction - Set fact for SAP kernel files, move_or_copy_archives parameter set + ansible.builtin.set_fact: + sap_swpm_software_path: "{{ __sap_install_media_detect_software_main_directory }}/sap_swpm_download_basket" # for setting consecutive vars + ignore_errors: true + when: + - sap_install_media_detect_move_or_copy_archives + +- name: SAP Install Media Detect - Find files after extraction - Set fact for SAP kernel files, move_or_copy_archives parameter not set + ansible.builtin.set_fact: + sap_swpm_software_path: "{{ __sap_install_media_detect_software_main_directory }}" # for setting consecutive vars + ignore_errors: true + when: + - not sap_install_media_detect_move_or_copy_archives + +- name: SAP Install Media Detect - Find files after extraction - Find SAPCAR + ansible.builtin.shell: set -o pipefail && ls -1tr SAPCAR*.EXE | tail -1 + args: + chdir: "{{ __sap_install_media_detect_software_main_directory }}" + register: sap_swpm_sapcar_file_name_get + changed_when: false + +- name: SAP Install Media Detect - Find files after extraction - Find SAP_HANA_CLIENT for SAP SWPM + ansible.builtin.find: + paths: "{{ __sap_install_media_detect_software_main_directory }}" + recurse: true + file_type: directory + patterns: "SAP_HANA_CLIENT" + register: sap_hana_client_path + ignore_errors: true + when: + - sap_install_media_detect_db_client == 'saphana' + +- name: SAP Install Media Detect - Find files after extraction - Find IBM Db2 + ansible.builtin.find: + paths: "{{ __sap_install_media_detect_software_main_directory }}/ibmdb2_extracted" + recurse: true + file_type: directory + patterns: ".*LINUXX86_64.*" + use_regex: true + register: detect_directory_ibmdb2_extracted + when: sap_install_media_detect_db == 'ibmdb2' + +- name: SAP Install Media Detect - Find files after extraction - Find IBM Db2 Client + ansible.builtin.find: + paths: "{{ __sap_install_media_detect_software_main_directory }}/ibmdb2_client_extracted" + recurse: true + file_type: directory + patterns: ".*DATA_UNITS.*" + use_regex: true + register: detect_directory_ibmdb2_client_extracted + when: + - sap_install_media_detect_db_client == 'ibmdb2' + +- name: SAP Install Media Detect - Find files after extraction - Find Oracle DB + ansible.builtin.find: + paths: "{{ __sap_install_media_detect_software_main_directory }}/oracledb_extracted" + recurse: true + file_type: directory + patterns: ".*LINUX_X86_64.*" + use_regex: true + register: detect_directory_oracledb_extracted + when: sap_install_media_detect_db == 'oracledb' + +- name: SAP Install Media Detect - Find files after extraction - Find Oracle DB Client + ansible.builtin.find: + paths: "{{ __sap_install_media_detect_software_main_directory }}/oracledb_client_extracted" + recurse: true + file_type: directory + patterns: ".*OCL_LINUX_X86_64.*" + use_regex: true + register: detect_directory_oracledb_client_extracted + when: + - sap_install_media_detect_db_client == 'oracledb' + +- name: SAP Install Media Detect - Find files after extraction - Find SAP ASE + ansible.builtin.find: + paths: "{{ __sap_install_media_detect_software_main_directory }}/sapase_extracted" + recurse: true + file_type: directory + patterns: ".*SYBASE_LINUX.*" + use_regex: true + register: detect_directory_sapase_extracted + when: sap_install_media_detect_db == 'sapase' + +- name: SAP Install Media Detect - Find files after extraction - Find SAP ASE Client + ansible.builtin.find: + paths: "{{ __sap_install_media_detect_software_main_directory }}/sapase_client_extracted" + recurse: true + file_type: directory + patterns: "sybodbc" + use_regex: true + register: detect_directory_sapase_client_extracted + when: + - sap_install_media_detect_db_client == 'sapase' + +- name: SAP Install Media Detect - Find files after extraction - Find SAP MaxDB + ansible.builtin.find: + paths: "{{ __sap_install_media_detect_software_main_directory }}/sapmaxdb_extracted/" + recurse: true + file_type: directory + patterns: '.*MaxDB_7.9.*' + use_regex: true + register: detect_directory_sapmaxdb_extracted + when: sap_install_media_detect_db == 'sapmaxdb' + +- name: SAP Install Media Detect - Find files after extraction - Find SAPEXE + ansible.builtin.shell: ls SAPEXE_*.SAR + args: + chdir: "{{ sap_swpm_software_path }}" + register: sap_swpm_kernel_independent_file_name_get + changed_when: false + when: sap_install_media_detect_kernel + +- name: SAP Install Media Detect - Find files after extraction - Fail if more than one SAPEXE found + ansible.builtin.fail: + msg: "More than one SAPEXE file has been detected." + when: + - sap_install_media_detect_kernel + - sap_swpm_kernel_independent_file_name_get.stdout_lines | count > 1 + +- name: SAP Install Media Detect - Find files after extraction - Find SAPEXEDB, database unspecific - block + when: + - sap_install_media_detect_kernel + - sap_install_media_detect_kernel_db is not defined or + sap_install_media_detect_kernel_db | length == 0 + block: + + - name: SAP Install Media Detect - Find files after extraction - Find SAPEXEDB, database unspecific + ansible.builtin.shell: ls SAPEXEDB_*.SAR + args: + chdir: "{{ sap_swpm_software_path }}" + register: sap_swpm_kernel_dependent_file_name_get_db_unspecific + changed_when: false + + - name: SAP Install Media Detect - Find files after extraction - Fail if more than one SAPEXEDB file found, database unspecific + ansible.builtin.fail: + msg: "No, or more than one, SAPEXEDB file has been detected." + when: + - sap_swpm_kernel_dependent_file_name_get_db_unspecific.stdout_lines | count != 1 + +- name: SAP Install Media Detect - Find files after extraction - Find SAPEXEDB, database specific - block + when: + - sap_install_media_detect_kernel + - sap_install_media_detect_kernel_db is defined + - sap_install_media_detect_kernel_db | length > 0 + block: + + - name: SAP Install Media Detect - Find files after extraction - Find SAPEXEDB, database specific + ansible.builtin.shell: "{{ __sap_install_media_detect_sapfile_path }} -e --sapcar_file={{ __sap_install_media_detect_fact_sapcar_path }} SAPEXEDB_*.SAR" + args: + chdir: "{{ sap_swpm_software_path }}" + register: __sap_install_media_detect_register_db_dependent_kernel_files + changed_when: false + + - name: SAP Install Media Detect - Find files after extraction - Set fact with the results of the sapfile command + ansible.builtin.set_fact: + __sap_install_media_detect_fact_db_dependent_kernel_files_sapfile_results: "{{ __sap_install_media_detect_fact_db_dependent_kernel_files_sapfile_results + [__new_dict] }}" + loop: "{{ __sap_install_media_detect_register_db_dependent_kernel_files.stdout_lines }}" + vars: + __new_dict: + file: "{{ item.split(';')[0] }}" + sap_file_type: "{{ item.split(';')[1] }}" + + - name: SAP Install Media Detect - Find files after extraction - Fail if none, or more than one, SAPEXEDB file for SAP HANA is present + ansible.builtin.fail: + msg: "No, or more than one, DB dependent SAP Kernel file for SAP HANA found" + when: + - sap_install_media_detect_kernel_db == 'saphana' + - __sap_install_media_detect_fact_db_dependent_kernel_files_sapfile_results | selectattr('sap_file_type', 'search', 'sap_kernel_db_hdb') | length != 1 + + - name: SAP Install Media Detect - Find files after extraction - Set the kernel dependent file name for SAP HANA + ansible.builtin.set_fact: + sap_swpm_kernel_dependent_file_name_get_db_specific: "{{ (__sap_install_media_detect_fact_db_dependent_kernel_files_sapfile_results | selectattr('sap_file_type', 'search', 'sap_kernel_db_hdb') | first).file }}" + when: + - sap_install_media_detect_kernel_db == 'saphana' + - __sap_install_media_detect_fact_db_dependent_kernel_files_sapfile_results | selectattr('sap_file_type', 'search', 'sap_kernel_db_hdb') | length == 1 + + - name: SAP Install Media Detect - Find files after extraction - Fail if none, or more than one, SAPEXEDB file for SAP ASE is present + ansible.builtin.fail: + msg: "No, or more than one, DB dependent SAP Kernel file for SAP ASE found" + when: + - sap_install_media_detect_kernel_db == 'sapase' + - __sap_install_media_detect_fact_db_dependent_kernel_files_sapfile_results | selectattr('sap_file_type', 'search', 'sap_kernel_db_ase') | length != 1 + + - name: SAP Install Media Detect - Find files after extraction - Set the kernel dependent file name for SAP ASE + ansible.builtin.set_fact: + sap_swpm_kernel_dependent_file_name_get_db_specific: "{{ (__sap_install_media_detect_fact_db_dependent_kernel_files_sapfile_results | selectattr('sap_file_type', 'search', 'sap_kernel_db_ase') | first).file }}" + when: + - sap_install_media_detect_kernel_db == 'sapase' + - __sap_install_media_detect_fact_db_dependent_kernel_files_sapfile_results | selectattr('sap_file_type', 'search', 'sap_kernel_db_ase') | length == 1 + + - name: SAP Install Media Detect - Find files after extraction - Fail if none, or more than one, SAPEXEDB file for SAP MAXDB is present + ansible.builtin.fail: + msg: "No, or more than one, DB dependent SAP Kernel file for SAP MAXDB found" + when: + - sap_install_media_detect_kernel_db == 'sapmaxdb' + - __sap_install_media_detect_fact_db_dependent_kernel_files_sapfile_results | selectattr('sap_file_type', 'search', 'sap_kernel_db_ada') | length != 1 + + - name: SAP Install Media Detect - Find files after extraction - Set the kernel dependent file name for SAP MAXDB + ansible.builtin.set_fact: + sap_swpm_kernel_dependent_file_name_get_db_specific: "{{ (__sap_install_media_detect_fact_db_dependent_kernel_files_sapfile_results | selectattr('sap_file_type', 'search', 'sap_kernel_db_ada') | first).file }}" + when: + - sap_install_media_detect_kernel_db == 'sapmaxdb' + - __sap_install_media_detect_fact_db_dependent_kernel_files_sapfile_results | selectattr('sap_file_type', 'search', 'sap_kernel_db_ada') | length == 1 + + - name: SAP Install Media Detect - Find files after extraction - Fail if none, or more than one, SAPEXEDB file for Oracle DB is present + ansible.builtin.fail: + msg: "No, or more than one, DB dependent SAP Kernel file for Oracle DB found" + when: + - sap_install_media_detect_kernel_db == 'oracledb' + - __sap_install_media_detect_fact_db_dependent_kernel_files_sapfile_results | selectattr('sap_file_type', 'search', 'sap_kernel_db_ora') | length != 1 + + - name: SAP Install Media Detect - Find files after extraction - Set the kernel dependent file name for Oracle DB + ansible.builtin.set_fact: + sap_swpm_kernel_dependent_file_name_get_db_specific: "{{ (__sap_install_media_detect_fact_db_dependent_kernel_files_sapfile_results | selectattr('sap_file_type', 'search', 'sap_kernel_db_ora') | first).file }}" + when: + - sap_install_media_detect_kernel_db == 'oracledb' + - __sap_install_media_detect_fact_db_dependent_kernel_files_sapfile_results | selectattr('sap_file_type', 'search', 'sap_kernel_db_ora') | length == 1 + + - name: SAP Install Media Detect - Find files after extraction - Fail if none, or more than one, SAPEXEDB file for IBM Db2 is present + ansible.builtin.fail: + msg: "No, or more than one, DB dependent SAP Kernel file for IBM Db2 found" + when: + - sap_install_media_detect_kernel_db == 'ibmdb2' + - __sap_install_media_detect_fact_db_dependent_kernel_files_sapfile_results | selectattr('sap_file_type', 'search', 'sap_kernel_db_db6') | length != 1 + + - name: SAP Install Media Detect - Find files after extraction - Set the kernel dependent file name for IBM Db2 + ansible.builtin.set_fact: + sap_swpm_kernel_dependent_file_name_get_db_specific: "{{ (__sap_install_media_detect_fact_db_dependent_kernel_files_sapfile_results | selectattr('sap_file_type', 'search', 'sap_kernel_db_db6') | first).file }}" + when: + - sap_install_media_detect_kernel_db == 'ibmdb2' + - __sap_install_media_detect_fact_db_dependent_kernel_files_sapfile_results | selectattr('sap_file_type', 'search', 'sap_kernel_db_db6') | length == 1 + +- name: SAP Install Media Detect - Find files after extraction - Find IGS, latest version + ansible.builtin.shell: set -o pipefail && ls -1tr igsexe*.sar | tail -1 + args: + chdir: "{{ sap_swpm_software_path }}" + register: sap_swpm_igs_file_name_get + changed_when: false + when: sap_install_media_detect_igs + +- name: SAP Install Media Detect - Find files after extraction - Find IGS Helper, latest version + ansible.builtin.shell: set -o pipefail && ls -1tr igshelper*.sar | tail -1 + args: + chdir: "{{ sap_swpm_software_path }}" + register: sap_swpm_igs_helper_file_name_get + changed_when: false + when: sap_install_media_detect_igs + +- name: SAP Install Media Detect - Find files after extraction - Find WEBDISP + ansible.builtin.shell: ls SAPWEBDISP_*.SAR + args: + chdir: "{{ sap_swpm_software_path }}" + register: sap_swpm_web_dispatcher_file_name_get + ignore_errors: true + changed_when: false + when: sap_install_media_detect_webdisp + +- name: SAP Install Media Detect - Find files after extraction - Fail if more than one WEBDISP found + ansible.builtin.fail: + msg: "More than one SAPWEBDISP file has been detected." + when: + - sap_install_media_detect_webdisp + - sap_swpm_web_dispatcher_file_name_get.stdout_lines | count > 1 + +- name: SAP Install Media Detect - Find files after extraction - Find Maintenance Planner Stack XML file + ansible.builtin.shell: set -o pipefail && ls -1tr *.xml | tail -1 + args: + chdir: "{{ sap_swpm_software_path }}" + register: sap_swpm_mp_xml_file_name_get + changed_when: false + when: sap_install_media_detect_mpstack + +- name: SAP Install Media Detect - Find files after extraction - Find SAP ECC Export + ansible.builtin.find: + paths: "{{ __sap_install_media_detect_software_main_directory }}/sap_export_ecc_extracted" + recurse: true + file_type: directory + patterns: '.*DATA_UNITS.*' + use_regex: true + register: detect_directory_ecc_export_extracted + when: sap_install_media_detect_export == 'sapecc' + +- name: SAP Install Media Detect - Find files after extraction - Find SAP ECC IDES Export + ansible.builtin.find: + paths: "{{ __sap_install_media_detect_software_main_directory }}/sap_export_ecc_ides_extracted" + recurse: true + file_type: directory + patterns: '.*EXP.*' + use_regex: true + register: detect_directory_ecc_ides_export_extracted + when: sap_install_media_detect_export == 'sapecc_ides' + +- name: SAP Install Media Detect - Find files after extraction - Find SAP S/4HANA Export + ansible.builtin.find: + paths: "{{ __sap_install_media_detect_software_main_directory }}" + recurse: true + file_type: file + patterns: '.*S4.*EXPORT.*' + use_regex: true + register: s4hana_export_files + when: sap_install_media_detect_export == 'saps4hana' + +- name: SAP Install Media Detect - Find files after extraction - Find SAP BW/4HANA Export + ansible.builtin.find: + paths: "{{ __sap_install_media_detect_software_main_directory }}" + recurse: true + file_type: file + patterns: '.*BW4.*EXPORT.*' + use_regex: true + register: bw4hana_export_files + when: sap_install_media_detect_export == 'sapbw4hana' + +- name: SAP Install Media Detect - Find files after extraction - Find SAP NetWeaver AS (ABAP) platform only Export + ansible.builtin.find: + paths: "{{ __sap_install_media_detect_software_main_directory }}/sap_export_nwas_abap_extracted" + recurse: true + file_type: directory + patterns: '.*DATA_UNITS.*' + use_regex: true + register: detect_directory_nwas_abap_export_extracted + when: sap_install_media_detect_export == 'sapnwas_abap' + +- name: SAP Install Media Detect - Find files after extraction - Find SAP NetWeaver AS (JAVA) platform only Export + ansible.builtin.find: + paths: "{{ __sap_install_media_detect_software_main_directory }}/sap_export_nwas_java_extracted" + recurse: true + file_type: directory + patterns: '.*DATA_UNITS.*' + use_regex: true + register: detect_directory_nwas_java_export_extracted + when: sap_install_media_detect_export == 'sapnwas_java' + +- name: SAP Install Media Detect - Find files after extraction - Find SAP Solution Manager (ABAP) platform only Export + ansible.builtin.find: + paths: "{{ __sap_install_media_detect_software_main_directory }}/sap_export_solman_abap_extracted" + recurse: true + file_type: directory + patterns: '.*DATA_UNITS.*' + use_regex: true + register: detect_directory_solgmr_abap_export_extracted + when: sap_install_media_detect_export == 'sapsolman_abap' + +- name: SAP Install Media Detect - Find files after extraction - Find SAP Solution Manager (JAVA) platform only Export + ansible.builtin.find: + paths: "{{ __sap_install_media_detect_software_main_directory }}/sap_export_solman_java_extracted" + recurse: true + file_type: directory + patterns: '.*DATA_UNITS.*' + use_regex: true + register: detect_directory_solgmr_java_export_extracted + when: sap_install_media_detect_export == 'sapsolman_java' diff --git a/roles/sap_install_media_detect/tasks/main.yml b/roles/sap_install_media_detect/tasks/main.yml index 15afd825f..9f69cf1d3 100644 --- a/roles/sap_install_media_detect/tasks/main.yml +++ b/roles/sap_install_media_detect/tasks/main.yml @@ -1,5 +1,24 @@ --- +# The sapcar (SAPCAR.EXE) program is required for the detection of the SAP file types. It is detected in create_file_list_phase_1.yml +#- name: SAP Install Media Detect - Prepare - Set fact for the sapcar program +# ansible.builtin.set_fact: +# __sap_install_media_detect_fact_sapcar_path_for_sapfile: "{{ sap_install_media_detect_sapcar_path | d('sapcar') }}" + +- name: SAP Install Media Detect - Prepare - Provide sapfile utility + ansible.builtin.include_tasks: + file: prepare/provide_sapfile_utility.yml + apply: + tags: sap_install_media_detect_provide_sapfile_utility + tags: sap_install_media_detect_provide_sapfile_utility + +- name: SAP Install Media Detect - Prepare - Enable zip handling + ansible.builtin.include_tasks: + file: prepare/enable_zip_handling.yml + apply: + tags: sap_install_media_detect_zip_handling + tags: sap_install_media_detect_zip_handling + - name: SAP Install Media Detect - Prepare - Enable rar handling ansible.builtin.include_tasks: file: prepare/enable_rar_handling.yml @@ -14,12 +33,12 @@ tags: sap_install_media_detect_check_directories tags: sap_install_media_detect_check_directories -- name: SAP Install Media Detect - Create a list of all files +- name: SAP Install Media Detect - Create a list of all files, phase 1 ansible.builtin.include_tasks: - file: prepare/create_file_list.yml + file: prepare/create_file_list_phase_1.yml apply: - tags: sap_install_media_detect_create_file_list - tags: sap_install_media_detect_create_file_list + tags: sap_install_media_detect_create_file_list_phase_1 + tags: sap_install_media_detect_create_file_list_phase_1 - name: SAP Install Media Detect - Detect and if necessary rename zip and rar files without extension ansible.builtin.include_tasks: @@ -28,120 +47,47 @@ tags: sap_install_media_detect_add_file_extension tags: sap_install_media_detect_add_file_extension -- name: SAP Install Media Detect - Organize SAPCAR - ansible.builtin.include_tasks: detect_sapcar.yml - -- name: SAP Install Media Detect - Organize SAP HANA installation media files - ansible.builtin.include_tasks: detect_saphana.yml - when: - - sap_install_media_detect_db == "saphana" - -- name: SAP Install Media Detect - Organize SAP SWPM installation media files - ansible.builtin.include_tasks: detect_sapswpm.yml - when: - - sap_install_media_detect_swpm - -- name: SAP Install Media Detect - Organize SAP Host Agent installation media files - ansible.builtin.include_tasks: detect_saphostagent.yml - when: - - sap_install_media_detect_hostagent - -- name: SAP Install Media Detect - Organize SAP IGS installation media files - ansible.builtin.include_tasks: detect_sapigs.yml - when: - - sap_install_media_detect_igs - -- name: SAP Install Media Detect - Organize SAP Kernel installation media files - ansible.builtin.include_tasks: detect_sapkernel.yml - when: - - sap_install_media_detect_kernel - -- name: SAP Install Media Detect - Organize SAP Web Dispatcher installation media files - ansible.builtin.include_tasks: detect_sapwebdisp.yml - when: - - sap_install_media_detect_webdisp - -- name: SAP Install Media Detect - Complete Data Backup files for SAP HANA - ansible.builtin.include_tasks: detect_backup_saphana.yml - when: - - sap_install_media_detect_backup == "saphana" - -# Detect files which (historically) have filenames which are Numbered IDs only (e.g. 51054410_2 for SAP MaxDB 7.9) -# Leave to last so directory has less files to scan - -- name: SAP Install Media Detect - Organize SAP ASE installation media files - ansible.builtin.include_tasks: detect_sapanydb_sapase.yml - when: - - sap_install_media_detect_db == "sapase" - -- name: SAP Install Media Detect - Organize SAP MaxDB installation media files - ansible.builtin.include_tasks: detect_sapanydb_sapmaxdb.yml - when: - - sap_install_media_detect_db == "sapmaxdb" - -- name: SAP Install Media Detect - Organize Oracle DB installation media files - ansible.builtin.include_tasks: detect_sapanydb_oracledb.yml - when: - - sap_install_media_detect_db == "oracledb" - -- name: SAP Install Media Detect - Organize IBM Db2 installation media files - ansible.builtin.include_tasks: detect_sapanydb_ibmdb2.yml - when: - - sap_install_media_detect_db == "ibmdb2" - -- name: SAP Install Media Detect - EXPORT files for SAP ECC - ansible.builtin.include_tasks: detect_export_sapecc.yml - when: sap_install_media_detect_export == "sapecc" - -- name: SAP Install Media Detect - EXPORT files for SAP ECC IDES - ansible.builtin.include_tasks: detect_export_sapecc_ides.yml - when: sap_install_media_detect_export == "sapecc_ides" - -- name: SAP Install Media Detect - EXPORT files for SAP S/4HANA - ansible.builtin.include_tasks: detect_export_saps4hana.yml - when: - - sap_install_media_detect_export == "saps4hana" - -- name: SAP Install Media Detect - EXPORT files for SAP BW/4HANA - ansible.builtin.include_tasks: detect_export_sapbw4hana.yml - when: - - sap_install_media_detect_export == "sapbw4hana" - -- name: SAP Install Media Detect - EXPORT files for SAP NetWeaver AS (ABAP) platform only - ansible.builtin.include_tasks: detect_export_sapnwas_abap.yml - when: sap_install_media_detect_export == "sapnwas_abap" - -- name: SAP Install Media Detect - EXPORT files for SAP NetWeaver AS (JAVA) platform only - ansible.builtin.include_tasks: detect_export_sapnwas_java.yml - when: sap_install_media_detect_export == "sapnwas_java" - -- name: SAP Install Media Detect - EXPORT files for SAP Solution Manager (ABAP) - ansible.builtin.include_tasks: detect_export_sapsolman_abap.yml - when: - - sap_install_media_detect_export == "sapsolman_abap" +- name: SAP Install Media Detect - Move any files from subdirectories to main directory + ansible.builtin.include_tasks: + file: prepare/move_files_to_main_directory.yml + apply: + tags: sap_install_media_detect_move_files_to_main_directory + tags: sap_install_media_detect_move_files_to_main_directory + when: not sap_install_media_detect_file_server_only -- name: SAP Install Media Detection Completed - set global vars for subsequent Ansible Tasks - ansible.builtin.include_tasks: set_global_vars.yml +- name: SAP Install Media Detect - Create a list of all required files, phase 2 + ansible.builtin.include_tasks: + file: prepare/create_file_list_phase_2.yml + apply: + tags: sap_install_media_detect_create_file_list_phase_2 + tags: sap_install_media_detect_create_file_list_phase_2 + when: not sap_install_media_detect_file_server_only -# Output of detected SAP Software +- name: SAP Install Media Detect - Organize files + ansible.builtin.include_tasks: + file: organize_files.yml + apply: + tags: sap_install_media_detect_organize_files + tags: sap_install_media_detect_organize_files + when: not sap_install_media_detect_file_server_only -- name: SAP Install Media Detection Completed - Display Paths for SAP HANA - ansible.builtin.debug: - msg: - - "SAP HANA Path - {{ sap_hana_install_directory }}" - when: - - sap_install_media_detect_db == "saphana" +- name: SAP Install Media Detect - Find files after extraction + ansible.builtin.include_tasks: + file: find_files_after_extraction.yml + apply: + tags: sap_install_media_detect_find_files_after_extraction + tags: sap_install_media_detect_find_files_after_extraction + when: not sap_install_media_detect_file_server_only -- name: SAP Install Media Detection Completed - Display Paths for SAP SWPM - ansible.builtin.debug: - msg: - - "SAP SWPM Software Path - {{ sap_swpm_software_path }}" - - "SAP SWPM SAPCAR Path - {{ sap_swpm_sapcar_path }}" - - "SAP SWPM Path - {{ sap_swpm_swpm_path }}" - when: - - sap_install_media_detect_swpm +- name: SAP Install Media Detection Completed - Set global vars for subsequent Ansible tasks or roles + ansible.builtin.include_tasks: + file: set_global_vars.yml + apply: + tags: sap_install_media_detect_set_global_vars + tags: sap_install_media_detect_set_global_vars + when: not sap_install_media_detect_file_server_only -- name: SAP Install Media Detect - Cleanup - Disable the EPEL repo if necessary +- name: SAP Install Media Detection Completed - Cleanup - Disable the EPEL repo if necessary ansible.builtin.include_tasks: file: cleanup/disable-epel-repo.yml apply: @@ -149,4 +95,12 @@ tags: sap_install_media_detect_rar_handling when: - sap_install_media_detect_rar_package == 'EPEL' + - ansible_os_family == 'RedHat' - __sap_install_media_detect_register_rpm_q_epel.stdout != 'epel-release' + +- name: SAP Install Media Detect - Cleanup - Remove sapfile utility + ansible.builtin.include_tasks: + file: cleanup/remove_sapfile_utility.yml + apply: + tags: sap_install_media_detect_provide_sapfile_utility + tags: sap_install_media_detect_provide_sapfile_utility diff --git a/roles/sap_install_media_detect/tasks/organize_files.yml b/roles/sap_install_media_detect/tasks/organize_files.yml new file mode 100644 index 000000000..dea5bfb1c --- /dev/null +++ b/roles/sap_install_media_detect/tasks/organize_files.yml @@ -0,0 +1,249 @@ +--- + +- name: SAP Install Media Detect - Organize all files - Copy files to {{ sap_install_media_detect_target_directory }} + ansible.builtin.copy: + src: "{{ sap_install_media_detect_source_directory }}/{{ line_item.file }}" + dest: "{{ sap_install_media_detect_target_directory }}/{{ line_item.file }}" + remote_src: true + owner: root + group: root + mode: '0755' + loop: "{{ __sap_install_media_detect_fact_files_sapfile_results }}" + loop_control: + loop_var: line_item + when: sap_install_media_detect_source == 'remote_dir' + +- name: SAP Install Media Detect - Organize all files - Remove existing archive extraction directories + ansible.builtin.file: + path: "{{ __sap_install_media_detect_software_main_directory }}/{{ line_item.extraction_dir }}" + state: absent + loop: "{{ __sap_install_media_detect_fact_files_sapfile_results }}" + loop_control: + loop_var: line_item + when: + - sap_install_media_detect_extract_archives + - line_item.extract_archive == 'y' + - (line_item.archive_type == 'zip' or + line_item.archive_type == 'rarexe' or + line_item.archive_type == 'rar' or + line_item.archive_type == 'sapcar') + +- name: SAP Install Media Detect - Organize all files - Create archive extraction directories + ansible.builtin.file: + path: "{{ __sap_install_media_detect_software_main_directory }}/{{ line_item.extraction_dir }}" + state: directory + owner: root + group: root + mode: '0755' + loop: "{{ __sap_install_media_detect_fact_files_sapfile_results }}" + loop_control: + loop_var: line_item + when: + - sap_install_media_detect_extract_archives + - line_item.extract_archive == 'y' + - (line_item.archive_type == 'zip' or + line_item.archive_type == 'rarexe' or + line_item.archive_type == 'rar' or + line_item.archive_type == 'sapcar') + +- name: SAP Install Media Detect - Organize all files - Create target directories for archive files + ansible.builtin.file: + path: "{{ __sap_install_media_detect_software_main_directory }}/{{ line_item.target_dir }}" + state: directory + owner: root + group: root + mode: '0755' + loop: "{{ __sap_install_media_detect_fact_files_sapfile_results }}" + loop_control: + loop_var: line_item + when: + - sap_install_media_detect_move_or_copy_archives + - line_item.target_dir != 'auto' + - (line_item.archive_type == 'zip' or + line_item.archive_type == 'rarexe' or + line_item.archive_type == 'rar' or + line_item.archive_type == 'sapcar' or + line_item.archive_type == 'xml') + +- name: SAP Install Media Detect - Organize all files - Create target directory 'sap_hana' + ansible.builtin.file: + path: "{{ __sap_install_media_detect_software_main_directory }}/sap_hana" + state: directory + owner: root + group: root + mode: '0755' + loop: "{{ __sap_install_media_detect_fact_files_sapfile_results }}" + loop_control: + loop_var: line_item + when: + - sap_install_media_detect_move_or_copy_archives + - sap_install_media_detect_db | d('') == 'saphana' + - line_item.target_dir == 'auto' + +- name: SAP Install Media Detect - Organize all files - Create target directory 'sap_swpm_download_basket' + ansible.builtin.file: + path: "{{ __sap_install_media_detect_software_main_directory }}/sap_swpm_download_basket" + state: directory + owner: root + group: root + mode: '0755' + loop: "{{ __sap_install_media_detect_fact_files_sapfile_results }}" + loop_control: + loop_var: line_item + when: + - sap_install_media_detect_move_or_copy_archives + - sap_install_media_detect_swpm + - line_item.target_dir == 'auto' + +- name: SAP Install Media Detect - Organize all files - Extract zip export archive files to separate subdirectories + ansible.builtin.shell: "set -o pipefail && unzip {{ line_item.file }} -d {{ __sap_install_media_detect_software_main_directory }}/{{ line_item.extraction_dir }}/{{ (line_item.file | splitext)[0] }}" + args: + chdir: "{{ __sap_install_media_detect_software_main_directory }}" + loop: "{{ __sap_install_media_detect_fact_files_sapfile_results }}" + loop_control: + loop_var: line_item + when: + - sap_install_media_detect_extract_archives + - line_item.archive_type == 'zip' + - line_item.extract_archive == 'y' + - line_item.sap_file_type is search("export") + +- name: SAP Install Media Detect - Organize all files - Extract zip non-export archive files + ansible.builtin.shell: "set -o pipefail && unzip {{ line_item.file }} -d {{ __sap_install_media_detect_software_main_directory }}/{{ line_item.extraction_dir }}" + args: + chdir: "{{ __sap_install_media_detect_software_main_directory }}" + loop: "{{ __sap_install_media_detect_fact_files_sapfile_results }}" + loop_control: + loop_var: line_item + when: + - sap_install_media_detect_extract_archives + - line_item.archive_type == 'zip' + - line_item.extract_archive == 'y' + - not line_item.sap_file_type is search("export") + +- name: SAP Install Media Detect - Organize all files - Extract rar archive files + ansible.builtin.shell: "set -o pipefail && {{ __sap_install_media_detect_rar_extract }} {{ line_item.file }}{{ __sap_install_media_detect_rar_extract_directory_argument }} {{ __sap_install_media_detect_software_main_directory }}/{{ line_item.extraction_dir }}" + args: + chdir: "{{ __sap_install_media_detect_software_main_directory }}" + loop: "{{ __sap_install_media_detect_fact_files_sapfile_results }}" + loop_control: + loop_var: line_item + when: + - sap_install_media_detect_extract_archives + - line_item.archive_type == 'rarexe' + - line_item.extract_archive == 'y' + +# SAP HANA sapcar archive files have a directory structure with a single directory (e.g. SAP_HANA_DATBASE) which contains all files. +# We want the extracted files to be placed in extraction_dir under this directory name, allowing multiple directories in extraction_dir. +# So we create a temporary directory, move the file SIGNATURE.SMF (which the sapcar command extracts to the level above) to this directory, +# and then move the single directory to the extraction_dir. +- name: SAP Install Media Detect - Organize all files - Create temp dir for sapcar archive files - {{ __sap_install_media_detect_software_main_directory }}/tmp_extract + ansible.builtin.file: + path: "{{ __sap_install_media_detect_software_main_directory }}/tmp_extract" + state: directory + owner: root + group: root + mode: '0755' + +- name: SAP Install Media Detect - Organize all files - Extract HANA sapcar archive files + ansible.builtin.shell: >- + {{ __sap_install_media_detect_fact_sapcar_path }} + -R {{ __sap_install_media_detect_software_main_directory }}/tmp_extract + -xvf {{ __sap_install_media_detect_software_main_directory }}/{{ line_item.file }} + -manifest SIGNATURE.SMF + && extracted_dir=$(ls -d */) + && mv SIGNATURE.SMF $extracted_dir + && mkdir -p {{ __sap_install_media_detect_software_main_directory }}/{{ line_item.extraction_dir }} + && mv $extracted_dir {{ __sap_install_media_detect_software_main_directory }}/{{ line_item.extraction_dir }}/ + args: + chdir: "{{ __sap_install_media_detect_software_main_directory }}/tmp_extract" + loop: "{{ __sap_install_media_detect_fact_files_sapfile_results }}" + loop_control: + loop_var: line_item + when: + - sap_install_media_detect_extract_archives + - line_item.extract_archive == 'y' + - line_item.archive_type == 'sapcar' + - line_item.sap_file_type is search('saphana') + +- name: SAP Install Media Detect - Organize all files - Remove temp dir - {{ __sap_install_media_detect_software_main_directory }}/tmp_extract + ansible.builtin.file: + path: "{{ __sap_install_media_detect_software_main_directory }}/tmp_extract" + state: absent + +# Non-SAP HANA sapcar archive files can have various different directory structures: Can be all flat, or up to 13 directory levels. +# We want the extracted files to be placed in the extraction_dir for this file, each file tree having its own separate directory. +# So we can directly extract the sapcar files to the final extraction_dir. +- name: SAP Install Media Detect - Organize all files - Extract non-HANA sapcar archive files + ansible.builtin.command: >- + {{ __sap_install_media_detect_fact_sapcar_path }} + -R {{ __sap_install_media_detect_software_main_directory }}/{{ line_item.extraction_dir }} + -xvf {{ __sap_install_media_detect_software_main_directory }}/{{ line_item.file }} + -manifest SIGNATURE.SMF + args: + chdir: "{{ __sap_install_media_detect_software_main_directory }}/{{ line_item.extraction_dir }}" + loop: "{{ __sap_install_media_detect_fact_files_sapfile_results }}" + loop_control: + loop_var: line_item + when: + - sap_install_media_detect_extract_archives + - line_item.extract_archive == 'y' + - line_item.archive_type == 'sapcar' + - not line_item.sap_file_type is search('saphana') + +- name: SAP Install Media Detect - Organize all files - Copy certain files to 'sap_hana' directory + ansible.builtin.copy: + src: "{{ __sap_install_media_detect_software_main_directory }}/{{ line_item.file }}" + dest: "{{ __sap_install_media_detect_software_main_directory }}/sap_hana/{{ line_item.file }}" + remote_src: true + owner: root + group: root + mode: '0755' + loop: "{{ __sap_install_media_detect_fact_files_sapfile_results }}" + loop_control: + loop_var: line_item + when: + - sap_install_media_detect_move_or_copy_archives + - sap_install_media_detect_db | d('') == 'saphana' + - (line_item.sap_file_type == 'sapcar' or + line_item.sap_file_type == 'saphana_client' or + line_item.sap_file_type == 'sap_hostagent') + +- name: SAP Install Media Detect - Organize all files - Copy certain files to 'sap_swpm_download_basket' directory + ansible.builtin.copy: + src: "{{ __sap_install_media_detect_software_main_directory }}/{{ line_item.file }}" + dest: "{{ __sap_install_media_detect_software_main_directory }}/sap_swpm_download_basket/{{ line_item.file }}" + remote_src: true + owner: root + group: root + mode: '0755' + loop: "{{ __sap_install_media_detect_fact_files_sapfile_results }}" + loop_control: + loop_var: line_item + when: + - sap_install_media_detect_move_or_copy_archives + - sap_install_media_detect_swpm + - (line_item.sap_file_type == 'sapcar' or + line_item.sap_file_type == 'saphana_client' or + line_item.sap_file_type == 'sap_hostagent') + +- name: SAP Install Media Detect - Organize all files - Copy archive files into subdirectories + ansible.builtin.shell: "set -o pipefail && cp {{ __sap_install_media_detect_software_main_directory }}/{{ line_item.file }} {{ __sap_install_media_detect_software_main_directory }}/{{ line_item.target_dir }}/{{ line_item.file }}" + loop: "{{ __sap_install_media_detect_fact_files_sapfile_results }}" + loop_control: + loop_var: line_item + when: + - sap_install_media_detect_move_or_copy_archives + - line_item.copy_archive == 'y' + - line_item.sap_file_type != 'sapcar' + - line_item.sap_file_type != 'saphana_client' + - line_item.sap_file_type != 'sap_hostagent' + +- name: SAP Install Media Detect - Organize all files - Move archive files into subdirectories + ansible.builtin.shell: "set -o pipefail && mv {{ __sap_install_media_detect_software_main_directory }}/{{ line_item.file }} {{ __sap_install_media_detect_software_main_directory }}/{{ line_item.target_dir }}/{{ line_item.file }}" + loop: "{{ __sap_install_media_detect_fact_files_sapfile_results }}" + loop_control: + loop_var: line_item + when: + - sap_install_media_detect_move_or_copy_archives + - line_item.copy_archive == 'n' diff --git a/roles/sap_install_media_detect/tasks/prepare/check_directories.yml b/roles/sap_install_media_detect/tasks/prepare/check_directories.yml index f949f3957..a66b3acf7 100644 --- a/roles/sap_install_media_detect/tasks/prepare/check_directories.yml +++ b/roles/sap_install_media_detect/tasks/prepare/check_directories.yml @@ -1,5 +1,15 @@ --- +- name: SAP Install Media Detect - Prepare - Get info of 'sap_install_media_detect_source_directory' + ansible.builtin.stat: + path: "{{ sap_install_media_detect_source_directory }}" + register: __sap_install_media_detect_source_directory_stat + +- name: SAP Install Media Detect - Prepare - Check if 'sap_install_media_detect_source_directory' exists + ansible.builtin.fail: + msg: "FAIL: Directory {{ sap_install_media_detect_source_directory }} does not exist!" + when: not __sap_install_media_detect_source_directory_stat.stat.exists + - name: SAP Install Media Detect - Prepare - Check the status of 'sap_install_media_detect_target_directory' when: - sap_install_media_detect_target_directory is defined @@ -7,49 +17,61 @@ - sap_install_media_detect_target_directory | string | length > 0 block: + - name: SAP Install Media Detect - Prepare - Create 'sap_install_media_detect_target_directory' + ansible.builtin.file: + path: "{{ sap_install_media_detect_target_directory }}" + state: directory + owner: 'root' + group: 'root' + mode: '0755' + when: + - sap_install_media_detect_create_target_directory + - name: SAP Install Media Detect - Prepare - Get info of 'sap_install_media_detect_target_directory' ansible.builtin.stat: path: "{{ sap_install_media_detect_target_directory }}" register: __sap_install_media_detect_target_directory_stat + when: + - not sap_install_media_detect_create_target_directory - name: SAP Install Media Detect - Prepare - Check if 'sap_install_media_detect_target_directory' exists ansible.builtin.fail: msg: "FAIL: Directory {{ sap_install_media_detect_target_directory }} does not exist!" - when: not __sap_install_media_detect_target_directory_stat.stat.exists + when: + - not sap_install_media_detect_create_target_directory + - not __sap_install_media_detect_target_directory_stat.stat.exists - name: SAP Install Media Detect - Prepare - Check if 'sap_install_media_detect_target_directory' is writable ansible.builtin.assert: that: __sap_install_media_detect_target_directory_stat.stat.writeable fail_msg: "FAIL: Directory {{ sap_install_media_detect_target_directory }} is not writable!" success_msg: "PASS: Directory {{ sap_install_media_detect_target_directory }} is writable." + when: + - not sap_install_media_detect_create_target_directory - - name: SAP Install Media Detect - Prepare - Set the variable sap_install_media_detect_source in case of writable remote file system + - name: SAP Install Media Detect - Prepare - Set facts in case of remote file system' ansible.builtin.set_fact: sap_install_media_detect_source: 'remote_dir' + __sap_install_media_detect_software_main_directory: "{{ sap_install_media_detect_target_directory }}" - name: SAP Install Media Detect - Prepare - Check the status of 'sap_install_media_detect_source_directory' when: sap_install_media_detect_target_directory is undefined or - sap_install_media_detect_target_directory | string == "None" or + sap_install_media_detect_target_directory | string == 'None' or sap_install_media_detect_target_directory | string | length == 0 block: - - name: SAP Install Media Detect - Prepare - Get info of 'sap_install_media_detect_source_directory' - ansible.builtin.stat: - path: "{{ sap_install_media_detect_source_directory }}" - register: __sap_install_media_detect_source_directory_stat - - - name: SAP Install Media Detect - Prepare - Check if 'sap_install_media_detect_source_directory' exists - ansible.builtin.fail: - msg: "FAIL: Directory {{ sap_install_media_detect_source_directory }} does not exist!" - when: not __sap_install_media_detect_source_directory_stat.stat.exists - - name: SAP Install Media Detect - Prepare - Check if 'sap_install_media_detect_source_directory' is writable ansible.builtin.assert: that: __sap_install_media_detect_source_directory_stat.stat.writeable fail_msg: "FAIL: Directory {{ sap_install_media_detect_source_directory }} is not writable!" success_msg: "PASS: Directory {{ sap_install_media_detect_source_directory }} is writable." - - name: SAP Install Media Detect - Prepare - Set some variables in case of writable local file system + - name: SAP Install Media Detect - Prepare - Set facts in case of local file system' ansible.builtin.set_fact: sap_install_media_detect_source: 'local_dir' __sap_install_media_detect_software_main_directory: "{{ sap_install_media_detect_source_directory }}" + +- name: SAP Install Media Detect - Prepare - Status report + ansible.builtin.debug: + msg: "Reading from '{{ sap_install_media_detect_source_directory }}'. + Storing and extracting on '{{ __sap_install_media_detect_software_main_directory }}'." diff --git a/roles/sap_install_media_detect/tasks/prepare/create_file_list.yml b/roles/sap_install_media_detect/tasks/prepare/create_file_list_phase_1.yml similarity index 62% rename from roles/sap_install_media_detect/tasks/prepare/create_file_list.yml rename to roles/sap_install_media_detect/tasks/prepare/create_file_list_phase_1.yml index 11148dae3..3240c91ad 100644 --- a/roles/sap_install_media_detect/tasks/prepare/create_file_list.yml +++ b/roles/sap_install_media_detect/tasks/prepare/create_file_list_phase_1.yml @@ -4,33 +4,49 @@ # With implicit initialization (by using the default filter), the variables would be appended again if the role # was called more than once in a playbook. # See https://github.com/sap-linuxlab/community.sap_install/issues/402 . -- name: SAP Install Media Detect - Prepare - Initialize fact variables +- name: SAP Install Media Detect - Prepare - Initialize fact variables, phase 1 ansible.builtin.set_fact: - __sap_install_media_detect_fact_find_result: [] + __sap_install_media_detect_fact_find_result_phase_1: [] __sap_install_media_detect_fact_files_without_extension: [] __sap_install_media_detect_fact_files_without_extension_file_results: [] __sap_install_media_detect_fact_zip_files_without_extension: [] __sap_install_media_detect_fact_exe_files_without_extension: [] __sap_install_media_detect_fact_rar_files_without_extension: [] -- name: SAP Install Media Detect - Prepare - Create list of all files on the top level of 'sap_install_media_detect_source_directory' +- name: SAP Install Media Detect - Prepare - Create initial list of all files on the top level of 'sap_install_media_detect_source_directory' ansible.builtin.find: paths: "{{ sap_install_media_detect_source_directory }}" patterns: '*' recurse: false use_regex: false - register: __sap_install_media_detect_register_find_result + register: __sap_install_media_detect_register_find_result_phase_1 -- name: SAP Install Media Detect - Prepare - Set fact from find result +- name: SAP Install Media Detect - Prepare - Set fact from find result, phase 1 ansible.builtin.set_fact: - __sap_install_media_detect_fact_find_result: "{{ __sap_install_media_detect_fact_find_result + [item.path] }}" - loop: "{{ __sap_install_media_detect_register_find_result.files }}" + __sap_install_media_detect_fact_find_result_phase_1: "{{ __sap_install_media_detect_fact_find_result_phase_1 + [item.path] }}" + loop: "{{ __sap_install_media_detect_register_find_result_phase_1.files }}" + +# If more than one SAPCAR file is found, we will use the last one. +- name: SAP Install Media Detect - Prepare - Identify sapcar + ansible.builtin.set_fact: + __sap_install_media_detect_fact_sapcar_path: "{{ sap_install_media_detect_source_directory }}/{{ line_item | basename }}" + loop: "{{ __sap_install_media_detect_fact_find_result_phase_1 }}" + loop_control: + loop_var: line_item + when: line_item is search("SAPCAR") + +- name: SAP Install Media Detect - Prepare - Ensure sapcar is executable + ansible.builtin.file: + path: "{{ __sap_install_media_detect_fact_sapcar_path }}" + owner: root + group: root + mode: '0755' - name: SAP Install Media Detect - Prepare - Set fact with any file names without extension ansible.builtin.set_fact: __sap_install_media_detect_fact_files_without_extension: "{{ __sap_install_media_detect_fact_files_without_extension + [item] }}" when: (item | splitext)[1] | length == 0 - loop: "{{ __sap_install_media_detect_fact_find_result }}" + loop: "{{ __sap_install_media_detect_fact_find_result_phase_1 }}" - name: SAP Install Media Detect - Prepare - Iterate over files without extension and determine file type ansible.builtin.shell: set -o pipefail && file {{ line_item }} | cut -d ' ' -f 2- @@ -50,24 +66,35 @@ file: "{{ item.line_item | basename }}" file_type: "{{ item.stdout }}" -- name: SAP Install Media Detect - Prepare - Display the file dict +- name: SAP Install Media Detect - Prepare - Display the file dict, phase 1 ansible.builtin.debug: var: __sap_install_media_detect_fact_files_without_extension_file_results - name: SAP Install Media Detect - Prepare - Set fact with file names without extension and of type 'Zip archive data' ansible.builtin.set_fact: __sap_install_media_detect_fact_zip_files_without_extension: "{{ __sap_install_media_detect_fact_zip_files_without_extension + [item] }}" - when: item.file_type is search 'Zip archive data' + when: item.file_type is search("Zip archive data") loop: "{{ __sap_install_media_detect_fact_files_without_extension_file_results }}" - name: SAP Install Media Detect - Prepare - Set fact with file names without extension and of type 'RAR self-extracting archive' ansible.builtin.set_fact: __sap_install_media_detect_fact_exe_files_without_extension: "{{ __sap_install_media_detect_fact_exe_files_without_extension + [item] }}" - when: item.file_type is search 'RAR self-extracting archive' + when: item.file_type is search("RAR self-extracting archive") loop: "{{ __sap_install_media_detect_fact_files_without_extension_file_results }}" - name: SAP Install Media Detect - Prepare - Set fact with file names without extension and of type 'RAR archive data' ansible.builtin.set_fact: __sap_install_media_detect_fact_rar_files_without_extension: "{{ __sap_install_media_detect_fact_rar_files_without_extension + [item] }}" - when: item.file_type is search 'RAR archive data' + when: item.file_type is search("RAR archive data") loop: "{{ __sap_install_media_detect_fact_files_without_extension_file_results }}" + +- name: SAP Install Media Detect - Prepare - Fail if there is a zip or rar file without extension on read-only file system + ansible.builtin.fail: + msg: "There is at least one zip or rar file without extension on a read-only file system. + The file(s) cannot be renamed on this system, and without ending, the extraction of the such files might fail." + when: + - sap_install_media_detect_source == 'remote_dir' + - not __sap_install_media_detect_source_directory_stat.stat.writeable + - (__sap_install_media_detect_fact_zip_files_without_extension | length > 0 or + __sap_install_media_detect_fact_exe_files_without_extension | length > 0 or + __sap_install_media_detect_fact_rar_files_without_extension | length > 0) diff --git a/roles/sap_install_media_detect/tasks/prepare/create_file_list_phase_2.yml b/roles/sap_install_media_detect/tasks/prepare/create_file_list_phase_2.yml new file mode 100644 index 000000000..91268cb29 --- /dev/null +++ b/roles/sap_install_media_detect/tasks/prepare/create_file_list_phase_2.yml @@ -0,0 +1,371 @@ +--- + +# The fact variables are appended in tasks of this file, so they need to be initialized explicitly. +# With implicit initialization (by using the default filter), the variables would be appended again if the role +# was called more than once in a playbook. +# See https://github.com/sap-linuxlab/community.sap_install/issues/402 . +- name: SAP Install Media Detect - Prepare - Initialize fact variables, phase 2 + ansible.builtin.set_fact: + __sap_install_media_detect_fact_find_result_phase_2: [] + __sap_install_media_detect_fact_files_sapfile_results: [] + +- name: SAP Install Media Detect - Prepare - Create final list of all files on the top level of 'sap_install_media_detect_source_directory' + ansible.builtin.find: + paths: "{{ sap_install_media_detect_source_directory }}" + patterns: '*' + recurse: false + use_regex: false + register: __sap_install_media_detect_register_find_result_phase_2 + +- name: SAP Install Media Detect - Prepare - Set fact from find result, phase 2 + ansible.builtin.set_fact: + __sap_install_media_detect_fact_find_result_phase_2: "{{ __sap_install_media_detect_fact_find_result_phase_2 + [item.path] }}" + loop: "{{ __sap_install_media_detect_register_find_result_phase_2.files }}" + +- name: SAP Install Media Detect - Prepare - Iterate over files and determine file type + ansible.builtin.command: "{{ __sap_install_media_detect_sapfile_path }} -e --lsar_file={{ __sap_install_media_detect_rar_list.split(' ')[0] }} --sapcar_file={{ __sap_install_media_detect_fact_sapcar_path }} {{ line_item }}" + register: __sap_install_media_detect_register_files_phase_2 + loop: "{{ __sap_install_media_detect_fact_find_result_phase_2 }}" + loop_control: + loop_var: line_item + changed_when: false + +- name: SAP Install Media Detect - Prepare - Set fact with the results of the sapfile command + ansible.builtin.set_fact: + __sap_install_media_detect_fact_files_sapfile_results: "{{ __sap_install_media_detect_fact_files_sapfile_results + [__new_dict] }}" + loop: "{{ __sap_install_media_detect_register_files_phase_2.results }}" + vars: + __new_dict: + dir: "{{ item.stdout.split(';')[0] | dirname }}" + file: "{{ item.stdout.split(';')[0] | basename }}" + sap_file_type: "{{ item.stdout.split(';')[1] }}" + target_dir: "{{ item.stdout.split(';')[2] }}" + extraction_dir: "{{ item.stdout.split(';')[3] }}" + archive_type: "{{ item.stdout.split(';')[4] }}" + extract_archive: "{{ item.stdout.split(';')[5] }}" + copy_archive: "{{ item.stdout.split(';')[6] }}" + when: + (item.stdout.split(';')[1] == 'sapcar') or + (item.stdout.split(';')[1] == 'sap_jvm') or + (item.stdout.split(';')[1] == 'sap_mp_xml') or + (item.stdout.split(';')[1] == 'sap_unknown') or + (sap_install_media_detect_swpm and item.stdout.split(';')[1] == 'sap_swpm') or + (sap_install_media_detect_hostagent and item.stdout.split(';')[1] == 'sap_hostagent') or + (sap_install_media_detect_igs and item.stdout.split(';')[1] == 'sap_igs') or + (sap_install_media_detect_kernel and item.stdout.split(';')[1] == 'sap_kernel') or + (sap_install_media_detect_kernel and item.stdout.split(';')[1] is search('sap_kernel_db_')) or + (sap_install_media_detect_webdisp and item.stdout.split(';')[1] == 'sap_webdisp') or + (sap_install_media_detect_db == 'saphana' and ( + item.stdout.split(';')[1] == 'saphana' or + item.stdout.split(';')[1] == 'saphana_other' or + item.stdout.split(';')[1] == 'saphana_vch_afl') + ) or + (sap_install_media_detect_db_client == 'saphana' and item.stdout.split(';')[1] == 'saphana_client') or + (sap_install_media_detect_db == 'sapmaxdb' and item.stdout.split(';')[1] == 'sapmaxdb') or + (sap_install_media_detect_db == 'sapase' and item.stdout.split(';')[1] == 'sapase') or + (sap_install_media_detect_db_client == 'sapase' and item.stdout.split(';')[1] == 'sapase_client') or + (sap_install_media_detect_db == 'oracledb' and ( + item.stdout.split(';')[1] == 'oracledb' or + item.stdout.split(';')[1] == 'oracledb_tools') + ) or + (sap_install_media_detect_db_client == 'oracledb' and item.stdout.split(';')[1] == 'oracledb_client') or + (sap_install_media_detect_db == 'ibmdb2' and ( + item.stdout.split(';')[1] == 'ibmdb2' or + item.stdout.split(';')[1] == 'ibmdb2_license') + ) or + (sap_install_media_detect_db_client == 'ibmdb2' and item.stdout.split(';')[1] == 'ibmdb2_client') or + (sap_install_media_detect_export == 'saps4hana' and ( + item.stdout.split(';')[1] == 'sap_export_s4hana' or + item.stdout.split(';')[1] == 'sap_s4hana_lang') + ) or + (sap_install_media_detect_export == 'sapbw4hana' and ( + item.stdout.split(';')[1] == 'sap_export_bw4hana' or + item.stdout.split(';')[1] == 'sap_s4hana_lang') + ) or + (sap_install_media_detect_export == 'sapnwas_abap' and item.stdout.split(';')[1] == 'sap_export_nwas_abap') or + (sap_install_media_detect_export == 'sapsolman_abap' and item.stdout.split(';')[1] == 'sap_export_solman_abap') or + (sap_install_media_detect_export == 'sapnwas_java' and item.stdout.split(';')[1] == 'sap_export_nwas_java') or + (sap_install_media_detect_export == 'sapsolman_java' and item.stdout.split(';')[1] == 'sap_export_solman_java') or + (sap_install_media_detect_export == 'sapecc' and item.stdout.split(';')[1] == 'sap_export_ecc') or + (sap_install_media_detect_export == 'sapecc_ides' and item.stdout.split(';')[1] == 'sap_export_ecc_ides') + +- name: SAP Install Media Detect - Prepare - Asserts + when: + - sap_install_media_detect_assert_after_sapfile | d(true) + block: + - name: SAP Install Media Detect - Prepare - Assert that sapcar is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'sapcar') | length > 0 + fail_msg: "No sapcar file found" + + - name: SAP Install Media Detect - Prepare - Assert that swpm is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'sap_swpm') | length > 0 + fail_msg: "No file found for sap_swpm" + when: + - sap_install_media_detect_swpm + + - name: SAP Install Media Detect - Prepare - Assert that exactly one SAP Kernel DB independent is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'sap_kernel') | length > 0 + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('file', 'search', 'SAPEXE_') | length == 1 + fail_msg: "No, or more than one, DB independent SAP Kernel file found" + when: + - sap_install_media_detect_kernel + + - name: SAP Install Media Detect - Prepare - Assert that exactly one SAP Kernel DB dependent is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'search', 'sap_kernel_db_') | length > 0 + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('file', 'search', 'SAPEXEDB_') | length == 1 + fail_msg: "No, or more than one, DB dependent SAP Kernel file found" + when: + - sap_install_media_detect_kernel + - sap_install_media_detect_kernel_db is not defined + + - name: SAP Install Media Detect - Prepare - Assert that exactly one matching SAP Kernel DB dependent is present + when: sap_install_media_detect_kernel_db is defined + block: + + - name: SAP Install Media Detect - Prepare - Assert that exactly one SAP Kernel DB dependent for SAP HANA is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'search', 'sap_kernel_db_hdb') | length == 1 + fail_msg: "No, or more than one, DB dependent SAP Kernel file for SAP HANA found" + when: + - sap_install_media_detect_kernel_db == 'saphana' + + - name: SAP Install Media Detect - Prepare - Assert that exactly one SAP Kernel DB dependent for SAP ASE is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'search', 'sap_kernel_db_ase') | length == 1 + fail_msg: "No, or more than one, DB dependent SAP Kernel file for SAP ASE found" + when: + - sap_install_media_detect_kernel_db == 'sapase' + + - name: SAP Install Media Detect - Prepare - Assert that exactly one SAP Kernel DB dependent for SAP MAXDB is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'search', 'sap_kernel_db_ada') | length == 1 + fail_msg: "No, or more than one, DB dependent SAP Kernel file for SAP MAXDB found" + when: + - sap_install_media_detect_kernel_db == 'sapmaxdb' + + - name: SAP Install Media Detect - Prepare - Assert that exactly one SAP Kernel DB dependent for Oracle DB is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'search', 'sap_kernel_db_ora') | length == 1 + fail_msg: "No, or more than one, DB dependent SAP Kernel file for Oracle DB found" + when: + - sap_install_media_detect_kernel_db == 'oracledb' + + - name: SAP Install Media Detect - Prepare - Assert that exactly one SAP Kernel DB dependent for IBM Db2 is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'search', 'sap_kernel_db_db6') | length == 1 + fail_msg: "No, or more than one, DB dependent SAP Kernel file for IBM Db2 found" + when: + - sap_install_media_detect_kernel_db == 'ibmdb2' + + - name: SAP Install Media Detect - Prepare - Assert that SAP Host Agent is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'sap_hostagent') | length > 0 + fail_msg: "No SAP Host Agent file found" + when: + - sap_install_media_detect_hostagent + + - name: SAP Install Media Detect - Prepare - Assert that igsexe is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'sap_igs') | length > 0 + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('file', 'search', 'igsexe') | length > 0 + fail_msg: "No igsexe file found" + when: + - sap_install_media_detect_igs + + - name: SAP Install Media Detect - Prepare - Assert that igshelper is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'sap_igs') | length > 0 + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('file', 'search', 'igshelper') | length > 0 + fail_msg: "No igshelper file found" + when: + - sap_install_media_detect_igs + + - name: SAP Install Media Detect - Prepare - Assert that exactly one SAP WEBDISP is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'sap_webdisp') | length > 0 + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('file', 'search', 'SAPWEBDISP_') | length == 1 + fail_msg: "No, or more than one, SAPWEBDISP file found" + when: + - sap_install_media_detect_webdisp + + - name: SAP Install Media Detect - Prepare - Assert that saphana is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'saphana') | length > 0 + fail_msg: "No file found for saphana" + when: + - sap_install_media_detect_db == 'saphana' + + - name: SAP Install Media Detect - Prepare - Assert that saphana_client is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'saphana_client') | length > 0 + fail_msg: "No file found for saphana_client" + when: + - sap_install_media_detect_db_client == 'saphana' + + - name: SAP Install Media Detect - Prepare - Assert that sapase is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'sapase') | length > 0 + fail_msg: "No file found for sapase" + when: + - sap_install_media_detect_db == 'sapase' + + - name: SAP Install Media Detect - Prepare - Assert that sapase_client is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'sapase_client') | length > 0 + fail_msg: "No file found for sapase_client" + when: + - sap_install_media_detect_db_client == 'sapase' + + - name: SAP Install Media Detect - Prepare - Assert that sapmaxdb is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'sapmaxdb') | length > 0 + fail_msg: "No file found for sapmaxdb" + when: + - sap_install_media_detect_db == 'sapmaxdb' + + - name: SAP Install Media Detect - Prepare - Assert that oracledb is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'oracledb') | length > 0 + fail_msg: "No file found for oracledb" + when: + - sap_install_media_detect_db == 'oracledb' + + - name: SAP Install Media Detect - Prepare - Assert that oracledb_client is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'oracledb_client') | length > 0 + fail_msg: "No file found for oracledb_client" + when: + - sap_install_media_detect_db_client == 'oracledb' + + - name: SAP Install Media Detect - Prepare - Assert that ibmdb2 is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'ibmdb2') | length > 0 + fail_msg: "No file found for ibmdb2" + when: + - sap_install_media_detect_db == 'ibmdb2' + + - name: SAP Install Media Detect - Prepare - Assert that ibmdb2_client is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'ibmdb2_client') | length > 0 + fail_msg: "No file found for ibmdb2_client" + when: + - sap_install_media_detect_db_client == 'ibmdb2' + + - name: SAP Install Media Detect - Prepare - Assert that ibmdb2_license is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'ibmdb2_license') | length > 0 + fail_msg: "No file found for ibmdb2_license" + when: + - sap_install_media_detect_db == 'ibmdb2' + + - name: SAP Install Media Detect - Prepare - Assert that sap_export_s4hana is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'sap_export_s4hana') | length > 0 + fail_msg: "No file found for sap_export_s4hana" + when: + - sap_install_media_detect_export == 'saps4hana' + + - name: SAP Install Media Detect - Prepare - Assert that sap_export_bw4hana is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'sap_export_bw4hana') | length > 0 + fail_msg: "No file found for sap_export_bw4hana" + when: + - sap_install_media_detect_export == 'sapbw4hana' + + - name: SAP Install Media Detect - Prepare - Assert that sap_export_ecc is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'sap_export_ecc') | length > 0 + fail_msg: "No file found for sap_export_ecc" + when: + - sap_install_media_detect_export == 'sapecc' + + - name: SAP Install Media Detect - Prepare - Assert that sap_export_ecc_ides is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'sap_export_ecc_ides') | length > 0 + fail_msg: "No file found for sap_export_ecc_ides" + when: + - sap_install_media_detect_export == 'sapecc_ides' + + - name: SAP Install Media Detect - Prepare - Assert that sap_export_nwas_abap is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'sap_export_nwas_abap') | length > 0 + fail_msg: "No file found for sap_export_nwas_abap" + when: + - sap_install_media_detect_export == 'sapnwas_abap' + + - name: SAP Install Media Detect - Prepare - Assert that sap_export_nwas_java is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'sap_export_nwas_java') | length > 0 + fail_msg: "No file found for sap_export_nwas_java" + when: + - sap_install_media_detect_export == 'sapnwas_java' + + - name: SAP Install Media Detect - Prepare - Assert that sap_export_solman_abap is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'sap_export_solman_abap') | length > 0 + fail_msg: "No file found for sap_export_solman_abap" + when: + - sap_install_media_detect_export == 'sapsolman_abap' + + - name: SAP Install Media Detect - Prepare - Assert that sap_export_solman_java is present + ansible.builtin.assert: + that: + - __sap_install_media_detect_fact_files_sapfile_results | selectattr('sap_file_type', 'equalto', 'sap_export_solman_java') | length > 0 + fail_msg: "No file found for sap_export_solman_java" + when: + - sap_install_media_detect_export == 'sapsolman_java' + +#- name: SAP Install Media Detect - Prepare - Identify the sapcar program +# ansible.builtin.set_fact: +# __sap_install_media_detect_fact_sapcar_path: "{{ __sap_install_media_detect_software_main_directory }}/{{ item.line_item | basename }}" +# loop: "{{ __sap_install_media_detect_register_files_phase_2.results }}" +# when: item.stdout.split(';')[1] == 'sapcar' + +#- name: SAP Install Media Detect - Prepare - Ensure sapcar is executable +# ansible.builtin.file: +# path: "{{ __sap_install_media_detect_fact_sapcar_path }}" +# owner: root +# group: root +# mode: '0755' + +- name: SAP Install Media Detect - Prepare - Display the file dict, phase 2 + ansible.builtin.debug: + var: __sap_install_media_detect_fact_files_sapfile_results + +#- name: SAP Install Media Detect - Prepare - Display the path to the sapcar program +# ansible.builtin.debug: +# var: __sap_install_media_detect_fact_sapcar_path diff --git a/roles/sap_install_media_detect/tasks/prepare/enable_rar_handling.yml b/roles/sap_install_media_detect/tasks/prepare/enable_rar_handling.yml index 5b4e097ac..774154ac7 100644 --- a/roles/sap_install_media_detect/tasks/prepare/enable_rar_handling.yml +++ b/roles/sap_install_media_detect/tasks/prepare/enable_rar_handling.yml @@ -1,7 +1,9 @@ --- - name: SAP Install Media Detect - Prepare - Install the unar package from EPEL - when: sap_install_media_detect_rar_package == 'EPEL' + when: + - sap_install_media_detect_rar_package == 'EPEL' + - ansible_os_family == 'RedHat' block: # Reason for noqa: Too much effort for now to examine the output of the yum module for the presence of a package @@ -48,21 +50,35 @@ - name: SAP Install Media Detect - Prepare - EPEL - Set facts ansible.builtin.set_fact: - sap_install_media_detect_rar_list: '/usr/bin/lsar' - sap_install_media_detect_rar_extract: '/usr/bin/unar' - sap_install_media_detect_rar_extract_argument: ' -o' + __sap_install_media_detect_rar_list: '/usr/bin/lsar' + __sap_install_media_detect_rar_extract: '/usr/bin/unar' + __sap_install_media_detect_rar_extract_directory_argument: ' -o' -- name: SAP Install Media Detect - Prepare - Install an unrar package - when: sap_install_media_detect_rar_package != 'EPEL' + +- name: SAP Install Media Detect - Prepare - Install the unar package (SLES) + when: + - ansible_os_family == 'Suse' block: - - name: SAP Install Media Detect - Prepare - unrar - Install the unrar package + # Requires SLES Basesystem_Module_* to obtain package + - name: SAP Install Media Detect - Prepare - SLES - Install the unar package ansible.builtin.package: - name: "{{ sap_install_media_detect_rar_package }}" + name: unar state: present - - name: SAP Install Media Detect - Prepare - unrar - Set facts + - name: SAP Install Media Detect - Prepare - SLES - Set facts + ansible.builtin.set_fact: + __sap_install_media_detect_rar_list: '/usr/bin/lsar' + __sap_install_media_detect_rar_extract: '/usr/bin/unar' + __sap_install_media_detect_rar_extract_directory_argument: ' -o' + + +- name: SAP Install Media Detect - Prepare - Install a rar extractor package (no EPEL) + when: sap_install_media_detect_rar_package != 'EPEL' # When default is overriden + block: + + - name: SAP Install Media Detect - Prepare - rar extractor - Set facts ansible.builtin.set_fact: - sap_install_media_detect_rar_list: '/usr/bin/unrar lb' - sap_install_media_detect_rar_extract: '/usr/bin/unrar x' - sap_install_media_detect_rar_extract_argument: '' + __sap_install_media_detect_rar_list: "{{ sap_install_media_detect_rar_list }}" + __sap_install_media_detect_rar_extract: "{{ sap_install_media_detect_rar_extract }}" + __sap_install_media_detect_rar_extract_directory_argument: "{{ sap_install_media_detect_rar_extract_directory_argument }}" diff --git a/roles/sap_install_media_detect/tasks/prepare/enable_zip_handling.yml b/roles/sap_install_media_detect/tasks/prepare/enable_zip_handling.yml new file mode 100644 index 000000000..3c154e896 --- /dev/null +++ b/roles/sap_install_media_detect/tasks/prepare/enable_zip_handling.yml @@ -0,0 +1,6 @@ +--- + +- name: SAP Install Media Detect - Prepare - Ensure the presence of the 'unzip' package + ansible.builtin.package: + name: 'unzip' + state: present diff --git a/roles/sap_install_media_detect/tasks/prepare/move_files_to_main_directory.yml b/roles/sap_install_media_detect/tasks/prepare/move_files_to_main_directory.yml new file mode 100644 index 000000000..8b20bca14 --- /dev/null +++ b/roles/sap_install_media_detect/tasks/prepare/move_files_to_main_directory.yml @@ -0,0 +1,47 @@ +--- + +- name: SAP Install Media Detect - Prepare - Initialize fact variables, phase 1b + ansible.builtin.set_fact: + __sap_install_media_detect_fact_find_result_phase_1b: [] + +# If any files have been moved to non-extract subdirectories already, move them back to the top level, making the role idempotent +# Reason for noqa: When using pipefail and there is no result from the grep -v, this tail will fail but it should never fail +- name: SAP Install Media Detect - Prepare - Find existing non-extract subdirectories # noqa risky-shell-pipe + ansible.builtin.shell: ls -d {{ __sap_install_media_detect_software_main_directory }}/*/ | grep -v '_extracted' + register: __sap_install_media_detect_register_subdirectories_phase_1b + changed_when: false + failed_when: false + +- name: SAP Install Media Detect - Prepare - Create list of all files one level below '{{ __sap_install_media_detect_software_main_directory }}' + ansible.builtin.find: + paths: "{{ line_item }}" + patterns: '*' + recurse: false + use_regex: false + loop: + - "{{ __sap_install_media_detect_register_subdirectories_phase_1b.stdout_lines }}" + loop_control: + loop_var: line_item + register: __sap_install_media_detect_register_find_result_phase_1b + +- name: SAP Install Media Detect - Prepare - Set fact from find result, phase 1b + ansible.builtin.set_fact: + __sap_install_media_detect_fact_find_result_phase_1b: "{{ __sap_install_media_detect_fact_find_result_phase_1b + [item.1.path] }}" + with_subelements: + - "{{ __sap_install_media_detect_register_find_result_phase_1b.results }}" + - files + +# Reason for noqa: Too much additional code required for determing if anything has changed or not +- name: SAP Install Media Detect - Prepare - Move files back to '{{ __sap_install_media_detect_software_main_directory }}' # noqa no-changed-when + ansible.builtin.command: "mv {{ line_item }} {{ __sap_install_media_detect_software_main_directory }}/" + loop: "{{ __sap_install_media_detect_fact_find_result_phase_1b }}" + loop_control: + loop_var: line_item + +- name: SAP Install Media Detect - Prepare - Remove the subdirectories + ansible.builtin.file: + path: "{{ line_item }}" + state: absent + loop: "{{ __sap_install_media_detect_register_subdirectories_phase_1b.stdout_lines }}" + loop_control: + loop_var: line_item diff --git a/roles/sap_install_media_detect/tasks/prepare/provide_sapfile_utility.yml b/roles/sap_install_media_detect/tasks/prepare/provide_sapfile_utility.yml new file mode 100644 index 000000000..4572d739b --- /dev/null +++ b/roles/sap_install_media_detect/tasks/prepare/provide_sapfile_utility.yml @@ -0,0 +1,19 @@ +--- + +- name: SAP Install Media Detect - Prepare - Create temporary directory to store various files + ansible.builtin.tempfile: + state: directory + suffix: media_detect + register: __sap_install_media_detect_tmpdir + +- name: SAP Install Media Detect - Prepare - Copy file sapfile utility to '{{ __sap_install_media_detect_tmpdir.path }}' + ansible.builtin.copy: + src: tmp/sapfile + dest: "{{ __sap_install_media_detect_tmpdir.path }}/sapfile" + owner: root + group: root + mode: '0755' + +- name: SAP Install Media Detect - Prepare - Set fact for sapfile utility + ansible.builtin.set_fact: + __sap_install_media_detect_sapfile_path: "{{ __sap_install_media_detect_tmpdir.path }}/sapfile" diff --git a/roles/sap_install_media_detect/tasks/set_global_vars.yml b/roles/sap_install_media_detect/tasks/set_global_vars.yml index 8ccd8fcb6..659090141 100644 --- a/roles/sap_install_media_detect/tasks/set_global_vars.yml +++ b/roles/sap_install_media_detect/tasks/set_global_vars.yml @@ -1,126 +1,256 @@ --- -- name: SAP Install Media Detection Completed - set facts for SAP HANA +- name: SAP Install Media Detect - Detection completed - Initialize variables for collecting and displaying all variables ansible.builtin.set_fact: - sap_hana_install_software_directory: "{{ sap_hana_install_directory }}" # for sap_hana_install Ansible Role - sap_hana_install_software_extract_directory: "{{ sap_hana_install_directory }}/extracted" # for sap_hana_install Ansible Role - sap_swpm_cd_rdms_path: "{{ sap_hana_client_path.files[0].path }}" # for sap_swpm Ansible Role + __sap_install_media_detect_result: '' + __sap_install_media_detect_vars: '' + +- name: SAP Install Media Detect - Detection completed - Set fact for SAPCAR + ansible.builtin.set_fact: + sap_swpm_sapcar_path: "{{ __sap_install_media_detect_software_main_directory }}/" + sap_swpm_sapcar_file_name: "{{ sap_swpm_sapcar_file_name_get.stdout }}" + +- name: SAP Install Media Detect - Detection completed - Set fact for SWPM, move_or_copy_archives parameter set + ansible.builtin.set_fact: +# sap_swpm_software_path: "{{ __sap_install_media_detect_software_main_directory }}/sap_swpm/" # set in find_files_after_extraction.yml +# sap_swpm_install_directory: "{{ __sap_install_media_detect_software_main_directory }}/sap_swpm/" +# sap_swpm_install_directory: "{{ __sap_install_media_detect_software_main_directory }}/sap_swpm_download_basket/" # for sap_swpm Ansible Role + sap_swpm_install_directory: "{{ sap_swpm_software_path }}/" + sap_swpm_swpm_path: "{{ __sap_install_media_detect_software_main_directory }}/sap_swpm/" # for sap_swpm Ansible Role +# sap_swpm_sapcar_path: "{{ __sap_install_media_detect_software_main_directory }}/sap_swpm/" # for sap_swpm Ansible Role +# sap_swpm_sapcar_path: "{{ sap_swpm_software_path }}/" # for sap_swpm Ansible Role ignore_errors: true when: - - sap_install_media_detect_db == "saphana" + - sap_install_media_detect_move_or_copy_archives + - sap_install_media_detect_swpm -- name: SAP Install Media Detection Completed - set facts for IBM Db2 +- name: SAP Install Media Detect - Detection completed - Set fact for SWPM, move_or_copy_archives parameter not set ansible.builtin.set_fact: - sap_swpm_cd_ibmdb2_path: "{{ detect_directory_ibmdb2_extracted.files[0].path }}" # for sap_swpm Ansible Role - sap_swpm_cd_ibmdb2_client_path: "{{ detect_directory_ibmdb2_client_extracted.files[0].path }}" # for sap_swpm Ansible Role - ignore_errors: true +# sap_swpm_install_directory: "{{ __sap_install_media_detect_software_main_directory }}/" # for sap_swpm Ansible Role + sap_swpm_install_directory: "{{ sap_swpm_software_path }}/" + sap_swpm_swpm_path: "{{ sap_swpm_software_path }}/" # for sap_swpm Ansible Role when: - - sap_install_media_detect_db == "ibmdb2" + - not sap_install_media_detect_move_or_copy_archives + - sap_install_media_detect_swpm -- name: SAP Install Media Detection Completed - set facts for Oracle DB +- name: SAP Install Media Detect - Detection completed - Set facts for SAP HANA - sap_hana_install, move_or_copy_archives parameter set ansible.builtin.set_fact: - sap_anydb_install_oracle_extract_path: "{{ detect_directory_oracledb_extracted.files[0].path }}" # for sap_anydb_install_oracle Ansible Role - sap_swpm_cd_oracle_path: "{{ detect_directory_oracledb_extracted.files[0].path }}" # for sap_swpm Ansible Role - sap_swpm_cd_oracle_client_path: "{{ detect_directory_oracledb_client_extracted.files[0].path }}" # for sap_swpm Ansible Role + sap_hana_install_directory: "{{ __sap_install_media_detect_software_main_directory }}/sap_hana/" + sap_hana_install_software_directory: "{{ __sap_install_media_detect_software_main_directory }}/sap_hana/" # for sap_hana_install Ansible Role + sap_hana_install_software_extract_directory: "{{ __sap_install_media_detect_software_main_directory }}/sap_hana_extracted/" # for sap_hana_install Ansible Role ignore_errors: true when: - - sap_install_media_detect_db == "oracledb" + - sap_install_media_detect_move_or_copy_archives + - sap_install_media_detect_db == 'saphana' -- name: SAP Install Media Detection Completed - set facts for SAP ASE +- name: SAP Install Media Detect - Detection completed - Set facts for SAP HANA - sap_hana_install, move_or_copy_archives parameter not set ansible.builtin.set_fact: - sap_swpm_cd_sapase_path: "{{ detect_directory_sapase_extracted.files[0].path }}" # for sap_swpm Ansible Role - sap_swpm_cd_sapase_client_path: "{{ detect_directory_sapase_client_extracted.files[0].path }}" # for sap_swpm Ansible Role + sap_hana_install_directory: "{{ __sap_install_media_detect_software_main_directory }}/" + sap_hana_install_software_directory: "{{ __sap_install_media_detect_software_main_directory }}/" # for sap_hana_install Ansible Role +# sap_hana_install_software_extract_directory: "{{ __sap_install_media_detect_software_main_directory }}/sap_hana_extracted/" # for sap_hana_install Ansible Role ignore_errors: true when: - - sap_install_media_detect_db == "sapase" + - not sap_install_media_detect_move_or_copy_archives + - sap_install_media_detect_db == 'saphana' -- name: SAP Install Media Detection Completed - set facts for SAP MaxDB +- name: SAP Install Media Detect - Detection completed - Set facts for SAP HANA Client - sap_swpm ansible.builtin.set_fact: - sap_swpm_cd_sapmaxdb_path: "{{ detect_directory_sapmaxdb_extracted.files[0].path }}" # for sap_swpm Ansible Role + sap_swpm_cd_rdbms_path: "{{ sap_hana_client_path.files[0].path }}/" # for sap_swpm Ansible Role ignore_errors: true when: - - sap_install_media_detect_db == "sapmaxdb" + - sap_install_media_detect_move_or_copy_archives + - sap_install_media_detect_db_client == 'saphana' -- name: SAP Install Media Detection Completed - set facts for Export of SAP ECC +# In 'find_files_after_extraction.yml', we search for a directory named 'LINUXX86_64'. For the role sap_swpm, we need to set +# exactly this path +- name: SAP Install Media Detect - Detection completed - Set facts for IBM Db2 ansible.builtin.set_fact: - sap_swpm_cd_export_path: "{{ detect_directory_export_extracted.files[0].path }}" # for sap_swpm Ansible Role + sap_swpm_cd_ibmdb2_path: "{{ detect_directory_ibmdb2_extracted.files[0].path }}/" # for sap_swpm Ansible Role ignore_errors: true - when: - - sap_install_media_detect_export == "sapecc" + when: sap_install_media_detect_db == 'ibmdb2' -- name: SAP Install Media Detection Completed - set facts for Export of SAP ECC IDES +- name: SAP Install Media Detect - Detection completed - Set facts for IBM Db2 Client ansible.builtin.set_fact: - sap_swpm_cd_export_path: "{{ detect_directory_export_extracted.files[0].path | dirname | dirname }}" # for sap_swpm Ansible Role - sap_swpm_cd_export_pt1_path: "{{ (detect_directory_export_extracted.files | map(attribute='path') | map('dirname') | list | select() | unique)[0] }}" # for sap_swpm Ansible Role - sap_swpm_cd_export_pt2_path: "{{ (detect_directory_export_extracted.files | map(attribute='path') | map('dirname') | list | select() | unique)[1] }}" # for sap_swpm Ansible Role + sap_swpm_cd_ibmdb2_client_path: "{{ detect_directory_ibmdb2_client_extracted.files[0].path }}/" # for sap_swpm Ansible Role ignore_errors: true - when: - - sap_install_media_detect_export == "sapecc_ides" + when: sap_install_media_detect_db_client == 'ibmdb2' -- name: SAP Install Media Detection Completed - set facts for Export of SAP S/4HANA +# In 'find_files_after_extraction.yml', we search for a directory name which contains 'LINUX_X86_64'. For the role sap_swpm, we need +# to set the path which contains this directory, not the directory itself. For the Oracle client, we search for a directory name which +# contains 'OCL_LINUX_X86_64'. For the role sap_swpm, we also need the path which contains this directory. +- name: SAP Install Media Detect - Detection completed - Set facts for Oracle DB ansible.builtin.set_fact: - sap_swpm_cd_export_path: "{{ s4hana_export_files.files[0].path }}" # for sap_swpm Ansible Role + sap_anydb_install_oracle_extract_path: "{{ detect_directory_oracledb_extracted.files[0].path | dirname }}/" # for sap_anydb_install_oracle Ansible Role + sap_swpm_cd_oracle_path: "{{ detect_directory_oracledb_extracted.files[0].path | dirname }}/" # for sap_swpm Ansible Role ignore_errors: true - when: - - sap_install_media_detect_export == "saps4hana" + when: sap_install_media_detect_db == 'oracledb' -- name: SAP Install Media Detection Completed - set facts for Export of SAP BW/4HANA +- name: SAP Install Media Detect - Detection completed - Set facts for Oracle DB Client ansible.builtin.set_fact: - sap_swpm_cd_export_path: "{{ bw4hana_export_files.files[0].path }}" # for sap_swpm Ansible Role + sap_swpm_cd_oracle_client_path: "{{ detect_directory_oracledb_client_extracted.files[0].path | dirname }}/" # for sap_swpm Ansible Role ignore_errors: true - when: - - sap_install_media_detect_export == "sapbw4hana" + when: sap_install_media_detect_db_client == 'oracledb' -- name: SAP Install Media Detection Completed - set facts for Export of SAP NetWeaver AS (ABAP) platform only +# In 'find_files_after_extraction.yml', we search for a directory name which contains 'SYBASE_LINUX'. For the role sap_swpm, we need +# to set exactly this path. For the ASE client, we search for a directory which contains 'sybodbc'. For the role +# sap_swpm, we need to set exactly this path. +- name: SAP Install Media Detect - Detection completed - Set facts for SAP ASE ansible.builtin.set_fact: - sap_swpm_cd_export_path: "{{ detect_directory_export_extracted.files[0].path }}" # for sap_swpm Ansible Role + sap_swpm_cd_sapase_path: "{{ detect_directory_sapase_extracted.files[0].path }}/" # for sap_swpm Ansible Role ignore_errors: true - when: - - sap_install_media_detect_export == "sapnwas_abap" + when: sap_install_media_detect_db == 'sapase' -- name: SAP Install Media Detection Completed - set facts for Export of SAP NetWeaver AS (JAVA) platform only +- name: SAP Install Media Detect - Detection completed - Set facts for SAP ASE Client ansible.builtin.set_fact: - sap_swpm_cd_export_path: "{{ detect_directory_export_extracted.files[0].path }}" # for sap_swpm Ansible Role + sap_swpm_cd_sapase_client_path: "{{ detect_directory_sapase_client_extracted.files[0].path }}/" # for sap_swpm Ansible Role ignore_errors: true - when: - - sap_install_media_detect_export == "sapnwas_java" + when: sap_install_media_detect_db_client == 'sapase' -- name: SAP Install Media Detection Completed - set facts for Export of SAP Solution Manager (ABAP) +- name: SAP Install Media Detect - Detection completed - Set facts for SAP MaxDB ansible.builtin.set_fact: - sap_swpm_cd_export_path: "{{ detect_directory_export_extracted.files[0].path | dirname | dirname }}" # for sap_swpm Ansible Role - sap_swpm_cd_export_pt1_path: "{{ detect_directory_export_extracted.files[0].path }}" # for sap_swpm Ansible Role - sap_swpm_cd_export_pt2_path: "{{ detect_directory_export_extracted.files[1].path }}" # for sap_swpm Ansible Role + sap_swpm_cd_sapmaxdb_path: "{{ detect_directory_sapmaxdb_extracted.files[0].path }}/" # for sap_swpm Ansible Role ignore_errors: true + when: sap_install_media_detect_db == 'sapmaxdb' + +- name: SAP Install Media Detect - Detection completed - Set facts for SAPEXE + ansible.builtin.set_fact: + sap_swpm_kernel_independent_path: "{{ sap_swpm_software_path }}/" + sap_swpm_kernel_independent_file_name: "{{ sap_swpm_kernel_independent_file_name_get.stdout }}" + when: sap_install_media_detect_kernel + +- name: SAP Install Media Detect - Detection completed - Set facts for SAPEXEDB, unspecific + ansible.builtin.set_fact: + sap_swpm_kernel_dependent_path: "{{ sap_swpm_software_path }}/" + sap_swpm_kernel_dependent_file_name: "{{ sap_swpm_kernel_dependent_file_name_get_db_unspecific.stdout }}" when: - - sap_install_media_detect_export == "sapsolman_abap" + - sap_install_media_detect_kernel + - sap_install_media_detect_kernel_db is not defined or + sap_install_media_detect_kernel_db | length == 0 -- name: SAP Install Media Detection Completed - set facts for SAP SWPM +- name: SAP Install Media Detect - Detection completed - Set facts for SAPEXEDB, specific ansible.builtin.set_fact: - sap_swpm_sapcar_path: "{{ __sap_install_media_detect_software_main_directory }}/sap_swpm" # for sap_swpm Ansible Role - ignore_errors: true + sap_swpm_kernel_dependent_path: "{{ sap_swpm_software_path }}/" + sap_swpm_kernel_dependent_file_name: "{{ sap_swpm_kernel_dependent_file_name_get_db_specific }}" when: - - sap_install_media_detect_swpm + - sap_install_media_detect_kernel + - sap_install_media_detect_kernel_db is defined + - sap_install_media_detect_kernel_db | length > 0 + +- name: SAP Install Media Detect - Detection completed - Set facts for SAP IGS + ansible.builtin.set_fact: + sap_swpm_igs_path: "{{ sap_swpm_software_path }}/" + sap_swpm_igs_file_name: "{{ sap_swpm_igs_file_name_get.stdout }}" + when: sap_install_media_detect_igs + +- name: SAP Install Media Detect - Detection completed - Set facts for SAP IGS Helper + ansible.builtin.set_fact: + sap_swpm_igs_helper_path: "{{ sap_swpm_software_path }}/" + sap_swpm_igs_helper_file_name: "{{ sap_swpm_igs_helper_file_name_get.stdout }}" + when: sap_install_media_detect_igs -- name: SAP Install Media Detection Completed - set fact for displaying all variables +- name: SAP Install Media Detect - Detection completed - Set facts for SAP Maintenance Planner Stack XML files ansible.builtin.set_fact: - __sap_install_media_detect_vars="{{ __sap_install_media_detect_vars | d('') + item + ' = >' + lookup('vars', item, default='') + '<\n' }}" + sap_swpm_mp_stack_path: "{{ sap_swpm_software_path }}/" + sap_swpm_mp_stack_file_name: "{{ sap_swpm_mp_xml_file_name_get.stdout }}" + ignore_errors: true + when: sap_install_media_detect_mpstack + +- name: SAP Install Media Detect - Detection completed - Set facts for WebDisp + ansible.builtin.set_fact: + sap_swpm_web_dispatcher_path: "{{ sap_swpm_software_path }}/" + sap_swpm_web_dispatcher_file_name: "{{ sap_swpm_web_dispatcher_file_name_get.stdout }}" + ignore_errors: true + when: sap_install_media_detect_webdisp + +- name: SAP Install Media Detect - Detection completed - Set facts for Export of SAP ECC + ansible.builtin.set_fact: + sap_swpm_cd_export_path: "{{ detect_directory_ecc_export_extracted.files[0].path }}/" # for sap_swpm Ansible Role + ignore_errors: true + when: sap_install_media_detect_export == 'sapecc' + +- name: SAP Install Media Detect - Detection completed - Set facts for Export of SAP ECC IDES + ansible.builtin.set_fact: + sap_swpm_cd_export_path: "{{ detect_directory_ecc_ides_export_extracted.files[0].path | dirname | dirname }}/" # for sap_swpm Ansible Role + sap_swpm_cd_export_pt1_path: "{{ (detect_directory_ecc_ides_export_extracted.files | map(attribute='path') | map('dirname') | list | select() | unique)[0] }}/" # for sap_swpm Ansible Role + sap_swpm_cd_export_pt2_path: "{{ (detect_directory_ecc_ides_export_extracted.files | map(attribute='path') | map('dirname') | list | select() | unique)[1] }}/" # for sap_swpm Ansible Role + ignore_errors: true + when: sap_install_media_detect_export == 'sapecc_ides' + +- name: SAP Install Media Detect - Detection completed - Set facts for Export of SAP S/4HANA + ansible.builtin.set_fact: + sap_swpm_cd_export_path: "{{ s4hana_export_files.files[0].path | dirname }}" # for sap_swpm Ansible Role + ignore_errors: true + when: sap_install_media_detect_export == 'saps4hana' + +- name: SAP Install Media Detect - Detection completed - Set facts for Export of SAP BW/4HANA + ansible.builtin.set_fact: + sap_swpm_cd_export_path: "{{ bw4hana_export_files.files[0].path | dirname }}" # for sap_swpm Ansible Role + ignore_errors: true + when: sap_install_media_detect_export == 'sapbw4hana' + +- name: SAP Install Media Detect - Detection completed - Set facts for Export of SAP NetWeaver AS (ABAP) platform only + ansible.builtin.set_fact: + sap_swpm_cd_export_path: "{{ detect_directory_nwas_abap_export_extracted.files[0].path }}/" # directory DATA_UNITS, for sap_swpm Ansible Role + ignore_errors: true + when: sap_install_media_detect_export == 'sapnwas_abap' + +- name: SAP Install Media Detect - Detection completed - Set facts for Export of SAP NetWeaver AS (JAVA) platform only + ansible.builtin.set_fact: + sap_swpm_cd_export_path: "{{ detect_directory_nwas_java_export_extracted.files[0].path }}/" # directory DATA_UNITS, for sap_swpm Ansible Role + ignore_errors: true + when: sap_install_media_detect_export == 'sapnwas_java' + +- name: SAP Install Media Detect - Detection completed - Set facts for Export of SAP Solution Manager (ABAP) + ansible.builtin.set_fact: + sap_swpm_cd_export_path: "{{ detect_directory_solgmr_abap_export_extracted.files[0].path | dirname | dirname }}/" # for sap_swpm Ansible Role + sap_swpm_cd_export_pt1_path: "{{ detect_directory_solgmr_abap_export_extracted.files[0].path }}/" # directory DATA_UNITS, for sap_swpm Ansible Role + sap_swpm_cd_export_pt2_path: "{{ detect_directory_solgmr_abap_export_extracted.files[1].path }}/" # directory DATA_UNITS, for sap_swpm Ansible Role + ignore_errors: true + when: sap_install_media_detect_export == 'sapsolman_abap' + +- name: SAP Install Media Detect - Detection completed - Set facts for Export of SAP Solution Manager (JAVA) + ansible.builtin.set_fact: + sap_swpm_cd_export_path: "{{ detect_directory_solgmr_java_export_extracted.files[0].path }}/" # directory DATA_UNITS, for sap_swpm Ansible Role + ignore_errors: true + when: sap_install_media_detect_export == 'sapsolman_java' + +- name: SAP Install Media Detect - Detection completed - Set fact for displaying all variables + ansible.builtin.set_fact: + __sap_install_media_detect_result: "{{ __sap_install_media_detect_result | d('') + item + ';' + lookup('vars', item, default='') + '\n' }}" + __sap_install_media_detect_vars: "{{ __sap_install_media_detect_vars | d('') + item + ' = >' + lookup('vars', item, default='') + '<\n' }}" loop: + - sap_hana_install_directory - sap_hana_install_software_directory - sap_hana_install_software_extract_directory - - sap_swpm_cd_rdms_path - - sap_swpm_cd_ibmdb2_path - - sap_swpm_cd_ibmdb2_client_path - sap_anydb_install_oracle_extract_path + - sap_swpm_swpm_path + - sap_swpm_software_path + - sap_swpm_cd_ibmdb2_path - sap_swpm_cd_oracle_path - - sap_swpm_cd_oracle_client_path - sap_swpm_cd_sapase_path - - sap_swpm_cd_sapase_client_path - sap_swpm_cd_sapmaxdb_path + - sap_swpm_cd_rdbms_path + - sap_swpm_cd_ibmdb2_client_path + - sap_swpm_cd_oracle_client_path + - sap_swpm_cd_sapase_client_path - sap_swpm_cd_export_path - sap_swpm_cd_export_pt1_path - sap_swpm_cd_export_pt2_path - sap_swpm_sapcar_path + - sap_swpm_sapcar_file_name + - sap_swpm_igs_path + - sap_swpm_igs_file_name + - sap_swpm_igs_helper_path + - sap_swpm_igs_helper_file_name + - sap_swpm_kernel_dependent_path + - sap_swpm_kernel_dependent_file_name + - sap_swpm_kernel_independent_path + - sap_swpm_kernel_independent_file_name + - sap_swpm_web_dispatcher_path + - sap_swpm_web_dispatcher_file_name + - sap_swpm_mp_stack_path + - sap_swpm_mp_stack_file_name -- name: SAP Install Media Detection Completed - Display all variables +- name: SAP Install Media Detect - Detection completed - Display result ansible.builtin.debug: msg: "{{ __sap_install_media_detect_vars.split('\n')[:-1] }}" diff --git a/roles/sap_storage_setup/README.md b/roles/sap_storage_setup/README.md index 67b76cc1b..d30109f09 100644 --- a/roles/sap_storage_setup/README.md +++ b/roles/sap_storage_setup/README.md @@ -127,6 +127,13 @@ The type of service the target system is going to be configured for.
This can be a list of multiple types which apply to a single host.
If not defined, the default will be inherited from the global parameter `sap_host_type`. One of these parameters must be defined.
+### sap_storage_setup_multipath_enable_and_detect + +- _Type:_ `bool` +- _Default:_ `False` + +Define if multipathing should be enabled and dynamic multipath devices detected and used for the filesystem setup.
+ ### sap_storage_setup_sid required - _Type:_ `str` diff --git a/roles/sap_storage_setup/defaults/main.yml b/roles/sap_storage_setup/defaults/main.yml index 5dbd54980..583c2c386 100644 --- a/roles/sap_storage_setup/defaults/main.yml +++ b/roles/sap_storage_setup/defaults/main.yml @@ -4,6 +4,12 @@ sap_storage_setup_host_type: "{{ sap_host_type }}" sap_storage_setup_sid: "{{ sap_system_sid }}" +# By default do not look for multipath devices. +# When enabled, this includes +# - installation of necessary packages +# - enabling of related services +sap_storage_setup_multipath_enable_and_detect: false + # The instance_nr parameters are required for references at the bottom. sap_storage_setup_nwas_abap_ascs_instance_nr: '00' sap_storage_setup_nwas_abap_ers_instance_nr: '10' @@ -29,7 +35,7 @@ sap_storage_setup_nwas_java_ci_instance_nr: '21' #----------------------------------------------------------# sap_storage_setup_nfs_filesystem_type: nfs4 -sap_storage_setup_nfs_mount_options: 'hard,acl' +sap_storage_setup_nfs_mount_options: defaults sap_storage_setup_local_filesystem_type: xfs # subdirectories as per SAP requirements diff --git a/roles/sap_storage_setup/meta/argument_specs.yml b/roles/sap_storage_setup/meta/argument_specs.yml index aac9c9aa1..298fb2a47 100644 --- a/roles/sap_storage_setup/meta/argument_specs.yml +++ b/roles/sap_storage_setup/meta/argument_specs.yml @@ -143,6 +143,14 @@ argument_specs: required: true # type can be list or string, the code will convert it to a list + + sap_storage_setup_multipath_enable_and_detect: + default: false + description: + - Define if multipathing should be enabled and dynamic multipath devices detected and used for the filesystem setup. + required: false + type: bool + sap_storage_setup_sid: description: - SID of the SAP service. diff --git a/roles/sap_storage_setup/tasks/generic_tasks/configure_multipathing.yml b/roles/sap_storage_setup/tasks/generic_tasks/configure_multipathing.yml new file mode 100644 index 000000000..7274b25d5 --- /dev/null +++ b/roles/sap_storage_setup/tasks/generic_tasks/configure_multipathing.yml @@ -0,0 +1,117 @@ +--- +- name: SAP Storage Setup - (Multipathing) Install OS packages + ansible.builtin.package: + name: "{{ __sap_storage_setup_extra_packages_multipath }}" + state: present + +- name: SAP Storage Setup - (Multipathing) Make sure services are running + ansible.builtin.service: + name: "{{ mp_service_item }}" + state: started + loop: "{{ __sap_storage_setup_extra_services_multipath }}" + loop_control: + loop_var: mp_service_item + +# Scan the SCSI bus to make sure devices have been refreshed after multipath was enabled. +# Create /etc/multipath.conf if it does not exist yet. +- name: SAP Storage Setup - (Multipathing) Scan SCSI bus and create/refresh config + register: __sap_storage_setup_register_refresh + ansible.builtin.shell: | + rescan-scsi-bus.sh \ + && sleep 10 \ + && { + multipathd reconfigure || /sbin/mpathconf --enable + } + failed_when: false + changed_when: __sap_storage_setup_register_refresh.rc == 0 + +- name: SAP Storage Setup - (Multipathing) Refresh ansible device facts + ansible.builtin.setup: + gather_subset: + - "hardware" + +# Similar to generic device discovery and fs mapping (main.yml), but using different +# information from the ansible_devices facts to map the WWN instead of dynamic device names. + +# Logic: Collect devices which have +# - no "holders" +# - no "links.uuids" +# - no "partitions" +# - "wwn" defined +# - "size" matching any of the filesystems defined in {{ sap_storage_setup_new_mounts_fact }} + +- name: SAP Storage Setup - (Multipathing) Make a list of unused WWNs of the requested sizes + ansible.builtin.set_fact: + available_devices_multipath: | + {% set av_disks = [] %} + {% set all_disks = (ansible_devices | dict2items) %} + {% for disk in all_disks %} + {%- if disk.value.wwn is defined + and disk.value.links.uuids | length == 0 + and disk.value.partitions | length == 0 + and disk.value.holders | length == 0 + %} + {%- for fs in sap_storage_setup_new_mounts_fact %} + {%- if fs.disk_size is defined + and (fs.disk_size | string + 'GB') in (disk.value.size | regex_replace('(\.\d+\s*)', '')) %} + {%- set add_to_list = av_disks.append(disk) %} + {%- endif %} + {%- endfor %} + {%- endif %} + {%- endfor %} + {{ av_disks | items2dict }} + +# !! +# If the DISK MATCHING syntax has changed in the above, it must also +# be adjusted in the next task +# !! + +# This task assigns device names for each volume to be created. +# - sap_storage_setup_new_mounts_fact derived from extravars: sap_storage_setup_definition +# and is dynamically generated during runtime to list only unconfigured filesystems +# - ansible facts: ansible-devices + +# DM devices are used for discovery, but the actual WWN will be used for +# the filesystem mapping. + +- name: SAP Storage Setup - (Multipathing) Set fact for target filesystem device mapping + ansible.builtin.set_fact: + filesystem_device_map: "{{ filesystem_device_map | default([]) + __multipath_to_fs_device_map }}" + vars: + __multipath_to_fs_device_map: | + {% set device_map = [] %} + {% set av_dev = (available_devices_multipath | dict2items) %} + {% set assigned_dev = [] %} + {% for fs in sap_storage_setup_new_mounts_fact -%} + {% set matching_dev = [] -%} + + {%- if fs.disk_size is defined + and ('nfs' not in fs.filesystem_type | default(sap_storage_setup_local_filesystem_type)) + and fs.swap_path is not defined -%} + + {%- for dev in av_dev -%} + {%- if (fs.disk_size | string + 'GB') in (dev.value.size | regex_replace('(\.\d+\s*)', '')) + and dev.value.wwn not in assigned_dev + and matching_dev | length < (fs.lvm_lv_stripes | d('1') | int) %} + + {#- comment: assigned_dev is a list for keeping track of wwns that have been added already -#} + {%- set assigned = assigned_dev.append(dev.value.wwn) %} + + {#- comment: wwn prefix "0x" must be removed and a "3" prefixed -#} + {%- set add = matching_dev.append('/dev/mapper/3' + dev.value.wwn[2:]) %} + + {%- endif %} + {%- endfor %} + + {%- set extend = device_map.extend([ + { + 'device': matching_dev | join(','), + 'fstype': fs.filesystem_type | default(sap_storage_setup_local_filesystem_type), + 'mountpoint': fs.mountpoint | default(''), + 'name': fs.name, + 'size': fs.disk_size, + } + ]) %} + {%- endif %} + {%- endfor %} + {{ device_map }} diff --git a/roles/sap_storage_setup/tasks/generic_tasks/configure_nfs_filesystems.yml b/roles/sap_storage_setup/tasks/generic_tasks/configure_nfs_filesystems.yml index 4697ec2dc..303174207 100644 --- a/roles/sap_storage_setup/tasks/generic_tasks/configure_nfs_filesystems.yml +++ b/roles/sap_storage_setup/tasks/generic_tasks/configure_nfs_filesystems.yml @@ -94,7 +94,10 @@ # Put temporary tasks inside a block which will make sure # that even in case of failure the temporary mountpoint will be removed - name: SAP Storage Setup - Temporary steps for NFS directory structure - # Block global parameters + ### Block global parameters + # Stop execution of tasks after this block for any host, if one host + # failed a task in this block. + any_errors_fatal: true vars: attach_item: | {{ sap_storage_setup_definition @@ -110,6 +113,7 @@ register: sap_storage_setup_tmpnfs_register - name: SAP Storage Setup - ({{ nfs_item.name }}) Attach NFS host root for subdirectory verification/creation + throttle: 1 # avoid NFS request flooding and silent timeout failures (observed on MS Azure Files) ansible.posix.mount: path: "{{ sap_storage_setup_tmpnfs_register.path }}" src: "{{ attach_item.nfs_server | default(sap_storage_setup_nfs_server) }}" @@ -151,6 +155,7 @@ always: - name: SAP Storage Setup - ({{ nfs_item.name }}) Remove temporary NFS mount + throttle: 1 # avoid NFS request flooding and silent timeout failures (observed on MS Azure Files) ansible.posix.mount: path: "{{ sap_storage_setup_tmpnfs_register.path }}" state: absent @@ -172,6 +177,7 @@ # ##### - name: SAP Storage Setup - ({{ nfs_item.name }}) Mount NFS + throttle: 1 # avoid NFS request flooding and silent timeout failures (observed on MS Azure Files) ansible.posix.mount: path: "{{ mount_item.mountpoint }}" src: "{{ nfs_server }}/{{ mount_item.mount_src | regex_replace('^/', '') }}" diff --git a/roles/sap_storage_setup/tasks/generic_tasks/map_single_disks_to_filesystems.yml b/roles/sap_storage_setup/tasks/generic_tasks/map_single_disks_to_filesystems.yml new file mode 100644 index 000000000..b3754bfde --- /dev/null +++ b/roles/sap_storage_setup/tasks/generic_tasks/map_single_disks_to_filesystems.yml @@ -0,0 +1,142 @@ +--- +########## +# Creating a list of unused devices that match the requested filesystem sizes, using +# - definition of unconfigured filesystems: sap_storage_setup_new_mounts_fact +# - ansible facts: ansible_devices +# +######### + +- name: SAP Storage Setup - Make a list of unused disk devices of the requested sizes + ansible.builtin.set_fact: + available_devices: | + {% set av_disks = [] %} + {% set all_disks = (ansible_devices | dict2items) %} + {% for disk in all_disks %} + {%- for fs in sap_storage_setup_new_mounts_fact %} + {%- if not disk.key.startswith('dm-') + and disk.value.links.uuids | length == 0 + and disk.value.partitions | length == 0 + and fs.disk_size is defined + and (fs.disk_size | string + 'GB') in (disk.value.size | regex_replace('(\.\d+\s*)', '')) %} + {%- set add_to_list = av_disks.append(disk) %} + {%- endif %} + {%- endfor %} + {%- endfor %} + {{ av_disks | items2dict }} + +# !! +# If the DISK MATCHING syntax has changed in the above, it must also +# be adjusted in the next task +# !! + +########## +# This task assigns device names for each volume to be created. +# - sap_storage_setup_new_mounts_fact derived from extravars: sap_storage_setup_definition +# and is dynamically generated during runtime to list only unconfigured filesystems +# - ansible facts: ansible-devices +# +########## + + +# When multipathing is enabled, there will be a {{ filesystem_device_map }} +# defined already that is to be enhanced with single disk definitions, if +# applicable. + +- name: SAP Storage Setup - Set fact for target filesystem device mapping + ansible.builtin.set_fact: + filesystem_device_map: "{{ filesystem_device_map | default([]) + __single_disk_to_fs_device_map }}" + vars: + __single_disk_to_fs_device_map: | + {% set device_map = [] %} + {% set av_dev = (available_devices | dict2items) %} + {% set assigned_dev = [] %} + {% for fs in sap_storage_setup_new_mounts_fact -%} + {% set matching_dev = [] -%} + + {%- if fs.disk_size is defined + and 'nfs' not in fs.filesystem_type | default(sap_storage_setup_local_filesystem_type) + and fs.swap_path is not defined + and fs.name not in filesystem_device_map | default([]) | map(attribute="name") + -%} + + {%- for dev in av_dev -%} + {%- if (fs.disk_size | string + 'GB') in (dev.value.size | regex_replace('(\.\d+\s*)', '')) + and dev.key not in assigned_dev + and dev.value.holders | length == 0 + and matching_dev | length < (fs.lvm_lv_stripes | d('1') | int) %} + + {%- set assigned = assigned_dev.append(dev.key) %} + {%- set add = matching_dev.append('/dev/' + dev.key) %} + + {%- endif %} + {%- endfor %} + + {%- if matching_dev | length > 0 -%} + {%- set extend = device_map.extend([ + { + 'device': matching_dev | join(','), + 'fstype': fs.filesystem_type | default(sap_storage_setup_local_filesystem_type), + 'mountpoint': fs.mountpoint | default(''), + 'name': fs.name, + 'size': fs.disk_size, + } + ]) %} + {%- endif %} + {%- endif %} + {%- endfor %} + {{ device_map }} + + +# This task combines information to create a mapping list of devices to filesystems. +# Sources: +# - sap_storage_setup_new_mounts_fact derived from extravars: sap_storage_setup_definition +# and is dynamically generated during runtime to list only unconfigured filesystems +# - Ansible host facts: hostvars[host_node].ansible_devices +- name: SAP Storage Setup - Set fact for device to filesystem mapping + when: + - map_item.nfs_path is not defined + - '"nfs" not in map_item.filesystem_type' + - map_item.swap_path is not defined + - filesystem_device_map is defined + - filesystem_device_map | length > 0 + ansible.builtin.set_fact: + volume_map: "{{ volume_map + volume_element }}" + vars: + volume_map: [] + volume_element: + - filesystem_type: "{{ map_item.filesystem_type | default(sap_storage_setup_local_filesystem_type) }}" + mountpoint: "{{ map_item.mountpoint | default('') }}" + volume_group: "{{ map_item.lvm_vg_name | default('vg_' + map_item.name) }}" + volume_name: "{{ map_item.lvm_lv_name | default('lv_' + map_item.name) }}" + device: |- + {% for entry in filesystem_device_map %} + {%- if map_item.name == entry.name -%} + {{ entry.device }} + {%- endif %} + {%- endfor %} + pesize: "{{ map_item.lvm_vg_physical_extent_size | default('4') }}" + pv_opts: "{{ map_item.lvm_pv_options | default('') }}" + vg_opts: "{{ map_item.lvm_vg_options | default('') }}" + lv_opts: |- + {% set lvopts = [] %} + {% if map_item.lvm_lv_stripes is defined and + map_item.lvm_lv_stripes | int > 0 -%} + {% set addopt = lvopts.append('--stripes ' + map_item.lvm_lv_stripes | string) %} + {%- endif %} + {% if map_item.lvm_lv_stripe_size is defined and + map_item.lvm_lv_stripe_size | length > 0 -%} + {% set addopt = lvopts.append('--stripesize ' + map_item.lvm_lv_stripe_size) %} + {%- endif %} + {{ lvopts | join(' ') }} + + loop: "{{ sap_storage_setup_new_mounts_fact }}" + loop_control: + label: "{{ map_item.name }}" + loop_var: map_item + + +- name: SAP Storage Setup - Display local disk setup assignment + ansible.builtin.debug: + var: volume_map + when: + - volume_map is defined diff --git a/roles/sap_storage_setup/tasks/main.yml b/roles/sap_storage_setup/tasks/main.yml index 237d67467..d9e3b26ad 100644 --- a/roles/sap_storage_setup/tasks/main.yml +++ b/roles/sap_storage_setup/tasks/main.yml @@ -4,20 +4,20 @@ ansible.builtin.setup: gather_subset: - "distribution" + - "hardware" - name: SAP Storage Setup - Include OS specific vars ansible.builtin.include_vars: file: "{{ ansible_os_family }}.yml" - name: SAP Storage Setup - Install additional OS packages + when: __sap_storage_setup_extra_packages is defined ansible.builtin.package: - name: "{{ package_item }}" + name: "{{ __sap_storage_setup_extra_packages }}" state: present - loop: "{{ __sap_storage_setup_extra_packages }}" - loop_control: - loop_var: package_item - name: SAP Storage Setup - Make sure services are running + when: __sap_storage_setup_extra_services is defined ansible.builtin.service: name: "{{ service_item }}" state: started @@ -25,162 +25,78 @@ loop_control: loop_var: service_item +# Create a list of elements from {{ sap_storage_setup_definition }} for all +# mountpoint elements that are not already reported as mounted in ansible facts. + +- name: SAP Storage Setup - Determine which local filesystems are not configured yet + when: + - new_mounts_item.nfs_path is not defined + - ( + new_mounts_item.mountpoint is defined + and new_mounts_item.mountpoint not in ansible_mounts | map(attribute="mount") + ) + or + ( + new_mounts_item.filesystem_type == 'swap' + and ansible_swaptotal_mb < (new_mounts_item.disk_size * 1000) + ) + # Calculating with 1000 instead of 1024, because existing swaptotal is likely to be + # reported at a slightly reduced size due to volume/filesystem metadata. + ansible.builtin.set_fact: + sap_storage_setup_new_mounts_fact: "{{ sap_storage_setup_new_mounts_fact | default([]) + [new_mounts_item] }}" + loop: "{{ sap_storage_setup_definition }}" + loop_control: + loop_var: new_mounts_item + label: "{{ new_mounts_item.name }}" -################ -# Cloud Specific Pre-Tasks - call cloud specific pre tasks thru {{ sap_storage_cloud_type }}_main.yml -################ +# TODO: Cloud Specific Pre-Tasks - call cloud specific pre tasks thru {{ sap_storage_cloud_type }}_main.yml #- name: SAP Storage Setup - Preparation for '{{ sap_storage_cloud_type }}' # include_tasks: "{{ sap_storage_cloud_type }}_main.yml" - # TODO: verify that the number of disks matches the fs definition # TODO: add functionality to work with existing LVM volumes and skip disk assignment -########## -# Creating a list of unused devices that match the requested filesystem sizes, using -# - custom definition: sap_storage_setup_definition -# - ansible facts: ansible_devices -# -######### -- name: SAP Storage Setup - Make a list of unused disk devices of the requested sizes - ansible.builtin.set_fact: - available_devices: | - {% set av_disks = [] %} - {% set all_disks = (ansible_devices | dict2items) %} - {% for disk in all_disks %} - {%- for fs in sap_storage_setup_definition %} - {%- if disk.value.links.uuids | length == 0 - and disk.value.partitions | length == 0 - and fs.disk_size is defined - and (fs.disk_size | string + 'GB') in (disk.value.size | regex_replace('(\.\d+\s*)', '')) %} - {%- set add_to_list = av_disks.append(disk) %} - {%- endif %} - {%- endfor %} - {%- endfor %} - {{ av_disks | items2dict }} - -# !! -# If the DISK MATCHING syntax has changed in the above, it must also -# be adjusted in the next task -# !! - -# This task assigns device names for each volume to be created. -# - custom definition: sap_storage_setup_definition -# - ansible facts: ansible-devices - -- name: SAP Storage Setup - Set fact for target filesystem device mapping - ansible.builtin.set_fact: - filesystem_device_map: | - {% set device_map = [] %} - {% set av_dev = (available_devices | dict2items) %} - {% set assigned_dev = [] %} - {% for fs in sap_storage_setup_definition -%} - {% set matching_dev = [] -%} - - {%- if fs.disk_size is defined - and ('nfs' not in fs.filesystem_type | default(sap_storage_setup_local_filesystem_type)) - and fs.swap_path is not defined -%} - - {%- for dev in av_dev -%} - {%- if (fs.disk_size | string + 'GB') in (dev.value.size | regex_replace('(\.\d+\s*)', '')) - and dev.key not in assigned_dev - and dev.value.holders | length == 0 - and matching_dev | length < (fs.lvm_lv_stripes | d('1') | int) %} - - {%- set assigned = assigned_dev.append(dev.key) %} - {%- set add = matching_dev.append('/dev/' + dev.key) %} - - {%- endif %} - {%- endfor %} - - {%- if matching_dev | length > 0 -%} - {%- set extend = device_map.extend([ - { - 'device': matching_dev | join(','), - 'fstype': fs.filesystem_type | default(sap_storage_setup_local_filesystem_type), - 'mountpoint': fs.mountpoint | default(''), - 'name': fs.name, - 'size': fs.disk_size, - } - ]) %} - {%- endif %} - {%- endif %} - {%- endfor %} - {{ device_map }} - - -# This task combines information to create a mapping list of devices to filesystems. -# Sources: -# - Extravars definition: sap_storage_setup_definition -# - Ansible host facts: hostvars[host_node].ansible_devices -- name: SAP Storage Setup - Set fact for device to filesystem mapping - ansible.builtin.set_fact: - volume_map: "{{ volume_map + volume_element }}" - vars: - volume_map: [] - volume_element: - - filesystem_type: "{{ map_item.filesystem_type | default(sap_storage_setup_local_filesystem_type) }}" - mountpoint: "{{ map_item.mountpoint | default('') }}" - volume_group: "{{ map_item.lvm_vg_name | default('vg_' + map_item.name) }}" - volume_name: "{{ map_item.lvm_lv_name | default('lv_' + map_item.name) }}" - device: |- - {% for entry in filesystem_device_map %} - {%- if map_item.name == entry.name -%} - {{ entry.device }} - {%- endif %} - {%- endfor %} - pesize: "{{ map_item.lvm_vg_physical_extent_size | default('4') }}" - pv_opts: "{{ map_item.lvm_pv_options | default('') }}" - vg_opts: "{{ map_item.lvm_vg_options | default('') }}" - lv_opts: |- - {% set lvopts = [] %} - {% if map_item.lvm_lv_stripes is defined and - map_item.lvm_lv_stripes | int > 0 -%} - {% set addopt = lvopts.append('--stripes ' + map_item.lvm_lv_stripes | string) %} - {%- endif %} - {% if map_item.lvm_lv_stripe_size is defined and - map_item.lvm_lv_stripe_size | length > 0 -%} - {% set addopt = lvopts.append('--stripesize ' + map_item.lvm_lv_stripe_size) %} - {%- endif %} - {{ lvopts | join(' ') }} +# Multipathing before single device processing: +# When multipathing is enabled it will run device detection and fs mapping +# first and the following generic tasks will do the same for any non-multipathed +# devices in addition, if there are any left and filesystems not yet assigned +# with devices. - loop: "{{ sap_storage_setup_definition }}" - loop_control: - label: "{{ map_item.name }}" - loop_var: map_item +- name: SAP Storage Setup - Configure multipathing and map disks to target filesystems when: - - map_item.nfs_path is not defined - - '"nfs" not in map_item.filesystem_type' - - map_item.swap_path is not defined - - filesystem_device_map is defined - - filesystem_device_map | length > 0 - + - sap_storage_setup_multipath_enable_and_detect + - sap_storage_setup_new_mounts_fact is defined + ansible.builtin.include_tasks: + file: "{{ sap_storage_setup_cloud_type }}_tasks/configure_multipathing.yml" -- name: SAP Storage Setup - Display local disk setup assignment - ansible.builtin.debug: - var: volume_map +- name: SAP Storage Setup - Combine single disks and complete mapping definition when: - - volume_map is defined - + - sap_storage_setup_new_mounts_fact is defined + ansible.builtin.include_tasks: + file: "{{ sap_storage_setup_cloud_type }}_tasks/map_single_disks_to_filesystems.yml" -################ +# LVM setup will only be entered when there were +# - unconfigured mountpoints +# - unconfigured disks matching the unconfigured filesystem sizes - name: SAP Storage Setup - Configure Volume Groups and Logical Volumes - ansible.builtin.include_tasks: - file: "{{ sap_storage_setup_cloud_type }}_tasks/configure_local_filesystems.yml" when: - volume_map is defined - volume_map | length > 0 + ansible.builtin.include_tasks: + file: "{{ sap_storage_setup_cloud_type }}_tasks/configure_local_filesystems.yml" -# NOTE: The conditional of this task requires Jinja2 version >= 2.11.0 (released January 2020) +# NOTE: The "default" in the conditional of this task requires +# Jinja2 version >= 2.11.0 (released January 2020) # Reference: https://jinja.palletsprojects.com/en/3.1.x/templates/#jinja-filters.map - name: SAP Storage Setup - Configure swap ansible.builtin.include_tasks: file: "{{ sap_storage_setup_cloud_type }}_tasks/configure_swap.yml" when: - - '"swap" in sap_storage_setup_definition + - sap_storage_setup_new_mounts_fact is defined + - '"swap" in sap_storage_setup_new_mounts_fact | map(attribute="filesystem_type", default=sap_storage_setup_local_filesystem_type)' - name: SAP Storage Setup - Configure NFS filesystems diff --git a/roles/sap_storage_setup/vars/RedHat.yml b/roles/sap_storage_setup/vars/RedHat.yml index 0ecc0616d..ef952716b 100644 --- a/roles/sap_storage_setup/vars/RedHat.yml +++ b/roles/sap_storage_setup/vars/RedHat.yml @@ -2,13 +2,15 @@ # RHEL specific variables __sap_storage_setup_extra_packages: - - device-mapper-multipath - lvm2 - - lvm2-dbusd - - lvm2-libs - - lvm2-lockd - nfs-utils +# - lvm2-dbusd + +__sap_storage_setup_extra_packages_multipath: + - device-mapper-multipath + +#__sap_storage_setup_extra_services: +# - lvm2-lvmdbusd -__sap_storage_setup_extra_services: +__sap_storage_setup_extra_services_multipath: - multipathd - - lvm2-lvmdbusd diff --git a/roles/sap_storage_setup/vars/Suse.yml b/roles/sap_storage_setup/vars/Suse.yml index 47d3bf422..376d35e19 100644 --- a/roles/sap_storage_setup/vars/Suse.yml +++ b/roles/sap_storage_setup/vars/Suse.yml @@ -2,10 +2,14 @@ # SLES specific variables __sap_storage_setup_extra_packages: - - multipath-tools - lvm2 - nfs-client -__sap_storage_setup_extra_services: +__sap_storage_setup_extra_packages_multipath: + - multipath-tools + +#__sap_storage_setup_extra_services: +# - lvm2-lvmdbusd + +__sap_storage_setup_extra_services_multipath: - multipathd - - lvm2-lvmdbusd diff --git a/roles/sap_swpm/defaults/main.yml b/roles/sap_swpm/defaults/main.yml index 4434d9f79..f1e146786 100644 --- a/roles/sap_swpm/defaults/main.yml +++ b/roles/sap_swpm/defaults/main.yml @@ -138,7 +138,7 @@ sap_swpm_cd_export_pt1_path: sap_swpm_cd_export_pt2_path: sap_swpm_cd_language_path: sap_swpm_cd_java_path: -sap_swpm_cd_rdms_path: +sap_swpm_cd_rdbms_path: sap_swpm_cd_export_path: sap_swpm_cd_ibmdb2_path: sap_swpm_cd_ibmdb2_client_path: diff --git a/roles/sap_swpm/tasks/post_install.yml b/roles/sap_swpm/tasks/post_install.yml index 916249c3e..4e0d39968 100644 --- a/roles/sap_swpm/tasks/post_install.yml +++ b/roles/sap_swpm/tasks/post_install.yml @@ -33,3 +33,26 @@ - ' IP - {{ ansible_default_ipv4.address | d(ansible_all_ipv4_addresses[0]) }} ' # - ' Master Password - {{ sap_swpm_master_password }} ' # - ' DDIC 000 Password - {{ sap_swpm_ddic_000_password }} ' + +# SAP HANA Client will not be installed for any installation with SAP AnyDB +# and will only be installed alongside SAP NWAS PAS or AAS (not NWAS ASCS) +- name: SAP SWPM Post Install - Check for SAP HANA Client hdbuserstore + ansible.builtin.stat: + path: /usr/sap/{{ sap_swpm_sid }}/hdbclient/hdbuserstore + register: __sap_swpm_post_install_register_hdbuserstore_exists + +- name: SAP SWPM Post Install - Enforce Connection Info in SAP HANA Client hdbuserstore + ansible.builtin.shell: | + /usr/sap/{{ sap_swpm_sid }}/hdbclient/hdbuserstore \ + SET DEFAULT \ + {{ sap_swpm_db_host }}:3{{ sap_swpm_db_instance_nr }}13@{{ sap_swpm_db_sid }} \ + {{ sap_swpm_db_schema_abap }} '{{ sap_swpm_db_system_password }}' + args: + executable: /bin/bash + become: true + become_user: "{{ sap_swpm_sid | lower }}adm" + when: + - sap_swpm_install_saphostagent is defined and sap_swpm_install_saphostagent + - __sap_swpm_post_install_register_hdbuserstore_exists.stat.exists + register: __sap_swpm_post_install_register_hdbuserstore_connection + changed_when: __sap_swpm_post_install_register_hdbuserstore_connection is succeeded diff --git a/roles/sap_swpm/tasks/pre_install.yml b/roles/sap_swpm/tasks/pre_install.yml index 38c0e6478..7e0cb7a6f 100644 --- a/roles/sap_swpm/tasks/pre_install.yml +++ b/roles/sap_swpm/tasks/pre_install.yml @@ -20,7 +20,7 @@ sap_swpm_swpm_command_product_id: "SAPINST_EXECUTE_PRODUCT_ID={{ sap_swpm_product_catalog_id }}" # If SWPM is running a normal install Ansible Variable sap_swpm_swpm_command_virtual_hostname is blank # IF SWPM is running a HA installation, Ansible Variable sap_swpm_swpm_command_virtual_hostname is set and contains "SAPINST_USE_HOSTNAME={{ sap_swpm_virtual_hostname }} IS_HOST_LOCAL_USING_STRING_COMPARE=true" - # If SWPM is running a MP Stack XML installation, Ansible Variable sap_swpm_swpm_command_mp_stack is set and contains "SAPINST_STACK_XML={{ sap_swpm_mp_stack_path }}/{{ sap_swpm_mp_stack_file_name }}" + # If SWPM is running a MP Stack XML installation, Ansible Variable sap_swpm_swpm_command_mp_stack is set and contains "SAPINST_STACK_XML={{ sap_swpm_mp_stack_path }} + '/' (if needed) + {{ sap_swpm_mp_stack_file_name }}" sap_swpm_swpm_command_extra_args: "SAPINST_SKIP_DIALOGS=true SAPINST_START_GUISERVER=false {{ sap_swpm_swpm_command_virtual_hostname }} {{ sap_swpm_swpm_command_mp_stack }}" tags: sap_swpm_sapinst_commandline @@ -62,7 +62,7 @@ - " WEBDISP - {{ sap_swpm_web_dispatcher_path }}/{{ sap_swpm_web_dispatcher_file_name }} " - " SAPCAR - {{ sap_swpm_sapcar_path }}/{{ sap_swpm_sapcar_file_name }} " - " SWPM - {{ sap_swpm_swpm_path }}/{{ sap_swpm_swpm_sar_file_name }} " - - " MP Stack - {{ sap_swpm_mp_stack_path }}/{{ sap_swpm_mp_stack_file_name }} " + - " MP Stack - {{ (sap_swpm_mp_stack_path | d('', true) + '/' + sap_swpm_mp_stack_file_name | d('', true)) | regex_replace('//*', '/') }}" - " Backup - {{ sap_swpm_backup_location }} " - name: SAP SWPM - Installation Process diff --git a/roles/sap_swpm/tasks/pre_install/install_type/ha_maint_plan_stack_install.yml b/roles/sap_swpm/tasks/pre_install/install_type/ha_maint_plan_stack_install.yml index c725e3bf8..9995effc0 100644 --- a/roles/sap_swpm/tasks/pre_install/install_type/ha_maint_plan_stack_install.yml +++ b/roles/sap_swpm/tasks/pre_install/install_type/ha_maint_plan_stack_install.yml @@ -18,7 +18,7 @@ # Install using SAP Maintenance Planner Stack XML # Check for MP Stack XML if filename not given -- name: SAP SWPM Pre Install - MP Stack XML - Get from {{ sap_swpm_mp_stack_path }} +- name: SAP SWPM Pre Install - MP Stack XML - Search for MP_*.xml file in {{ sap_swpm_mp_stack_path }} ansible.builtin.shell: | ls MP*.xml args: @@ -31,7 +31,7 @@ (sap_swpm_mp_stack_file_name is none) or (sap_swpm_mp_stack_file_name | length == 0) -- name: SAP SWPM Pre Install - MP Stack XML - Set fact +- name: SAP SWPM Pre Install - MP Stack XML - Set fact for filename ansible.builtin.set_fact: sap_swpm_mp_stack_file_name: "{{ sap_swpm_mp_stack_file_get.stdout }}" # Test if variable string is not defined or None / blank @@ -41,22 +41,22 @@ (sap_swpm_mp_stack_file_name is none) or (sap_swpm_mp_stack_file_name | length == 0) -- name: SAP SWPM Pre Install - MP Stack XML - Set fact +- name: SAP SWPM Pre Install - MP Stack XML - Show File and Path ansible.builtin.debug: - msg: "SAP Maintenance Planner Stack XML is {{ sap_swpm_mp_stack_path }}/{{ sap_swpm_mp_stack_file_name }}" + msg: "SAP Maintenance Planner Stack XML is {{ (sap_swpm_mp_stack_path + '/' + sap_swpm_mp_stack_file_name) | regex_replace('//*', '/') }}" - name: SAP SWPM Pre Install - MP Stack XML - Set fact for SWPM injection ansible.builtin.set_fact: - sap_swpm_swpm_command_mp_stack: "SAPINST_STACK_XML={{ sap_swpm_mp_stack_path }}/{{ sap_swpm_mp_stack_file_name }}" + sap_swpm_swpm_command_mp_stack: "SAPINST_STACK_XML={{ (sap_swpm_mp_stack_path + '/' + sap_swpm_mp_stack_file_name) | regex_replace('//*', '/') }}" - name: SAP SWPM Pre Install - MP Stack XML - Ensure (1 of 2) SAP System ID is correct inside SAP Maintenance Plan Stack XML ansible.builtin.replace: - path: "{{ sap_swpm_mp_stack_path }}/{{ sap_swpm_mp_stack_file_name }}" + path: "{{ (sap_swpm_mp_stack_path + '/' + sap_swpm_mp_stack_file_name) | regex_replace('//*', '/') }}" regexp: '([A-Z][0-9])\w' replace: '{{ sap_swpm_sid | upper }}' diff --git a/roles/sap_swpm/tasks/pre_install/install_type/maint_plan_stack_install.yml b/roles/sap_swpm/tasks/pre_install/install_type/maint_plan_stack_install.yml index ee5dd79f3..3c33b3265 100644 --- a/roles/sap_swpm/tasks/pre_install/install_type/maint_plan_stack_install.yml +++ b/roles/sap_swpm/tasks/pre_install/install_type/maint_plan_stack_install.yml @@ -3,7 +3,7 @@ # Install using SAP Maintenance Planner Stack XML # Check for MP Stack XML if filename not given -- name: SAP SWPM Pre Install - MP Stack XML - Get from {{ sap_swpm_mp_stack_path }} +- name: SAP SWPM Pre Install - MP Stack XML - Search for MP_*.xml file in {{ sap_swpm_mp_stack_path }} ansible.builtin.shell: | ls MP*.xml args: @@ -16,7 +16,7 @@ (sap_swpm_mp_stack_file_name is none) or (sap_swpm_mp_stack_file_name | length == 0) -- name: SAP SWPM Pre Install - MP Stack XML - Set fact +- name: SAP SWPM Pre Install - MP Stack XML - Set fact for filename ansible.builtin.set_fact: sap_swpm_mp_stack_file_name: "{{ sap_swpm_mp_stack_file_get.stdout }}" # Test if variable string is not defined or None / blank @@ -26,22 +26,22 @@ (sap_swpm_mp_stack_file_name is none) or (sap_swpm_mp_stack_file_name | length == 0) -- name: SAP SWPM Pre Install - MP Stack XML - Set fact +- name: SAP SWPM Pre Install - MP Stack XML - Show File and Path ansible.builtin.debug: - msg: "SAP Maintenance Planner Stack XML is {{ sap_swpm_mp_stack_path }}/{{ sap_swpm_mp_stack_file_name }}" + msg: "SAP Maintenance Planner Stack XML is {{ (sap_swpm_mp_stack_path + '/' + sap_swpm_mp_stack_file_name) | regex_replace('//*', '/') }}" - name: SAP SWPM Pre Install - MP Stack XML - Set fact for SWPM injection ansible.builtin.set_fact: - sap_swpm_swpm_command_mp_stack: "SAPINST_STACK_XML={{ sap_swpm_mp_stack_path }}/{{ sap_swpm_mp_stack_file_name }}" + sap_swpm_swpm_command_mp_stack: "SAPINST_STACK_XML={{ (sap_swpm_mp_stack_path + '/' + sap_swpm_mp_stack_file_name) | regex_replace('//*', '/') }}" - name: SAP SWPM Pre Install - MP Stack XML - Ensure (1 of 2) SAP System ID is correct inside SAP Maintenance Plan Stack XML ansible.builtin.replace: - path: "{{ sap_swpm_mp_stack_path }}/{{ sap_swpm_mp_stack_file_name }}" + path: "{{ (sap_swpm_mp_stack_path + '/' + sap_swpm_mp_stack_file_name) | regex_replace('//*', '/') }}" regexp: '([A-Z][0-9])\w' replace: '{{ sap_swpm_sid | upper }}' diff --git a/roles/sap_swpm/tasks/swpm/detect_variables.yml b/roles/sap_swpm/tasks/swpm/detect_variables.yml index a73931037..59c08ad8c 100644 --- a/roles/sap_swpm/tasks/swpm/detect_variables.yml +++ b/roles/sap_swpm/tasks/swpm/detect_variables.yml @@ -2,68 +2,70 @@ # Detect Product ID - name: SAP SWPM - Detect Product ID - ansible.builtin.shell: | - set -o pipefail && sed -n '3p' {{ sap_swpm_tmpdir.path }}/inifile.params | awk 'NF{print $(NF-1)}' | tr -d \' + ansible.builtin.command: | + awk 'BEGIN{IGNORECASE=1;a=0} + /Product ID/&&a==0{a=1; gsub ("#", ""); gsub ("\047", ""); product_id=$NF} + END{print product_id}' {{ sap_swpm_tmpdir.path }}/inifile.params register: sap_swpm_inifile_product_id_detect changed_when: false # Set fact for product id -- name: Set SAP product ID +- name: SAP SWPM - Set SAP product ID ansible.builtin.set_fact: sap_swpm_product_catalog_id: "{{ sap_swpm_inifile_product_id_detect.stdout }}" -- name: Display SAP product ID +- name: SAP SWPM - Display SAP product ID ansible.builtin.debug: msg: - "Product ID is {{ sap_swpm_product_catalog_id }}" # Detect Software Path - name: SAP SWPM - Detect Software Path - ansible.builtin.shell: | - set -o pipefail && cat {{ sap_swpm_tmpdir.path }}/inifile.params | grep archives.downloadBasket | awk '{ print $3 }' + ansible.builtin.command: | + awk '!/^#/&&/archives.downloadBasket/{print $3}' {{ sap_swpm_tmpdir.path }}/inifile.params register: sap_swpm_inifile_software_path changed_when: false # Set fact for software path -- name: Set Software Path +- name: SAP SWPM - Set Software Path ansible.builtin.set_fact: sap_swpm_software_path: "{{ sap_swpm_inifile_software_path.stdout }}" -- name: Display SAP SID +- name: SAP SWPM - Display Software Path ansible.builtin.debug: msg: - "Software path is {{ sap_swpm_software_path }}" # Detect SID - name: SAP SWPM - Detect SID - ansible.builtin.shell: | - set -o pipefail && cat {{ sap_swpm_tmpdir.path }}/inifile.params | grep NW_GetSidNoProfiles.sid | awk '{ print $3 }' + ansible.builtin.command: | + awk '!/^#/&&/NW_GetSidNoProfiles.sid/{print $3}' {{ sap_swpm_tmpdir.path }}/inifile.params register: sap_swpm_inifile_sid changed_when: false # Set fact for SID -- name: Set SID +- name: SAP SWPM - Set SID ansible.builtin.set_fact: sap_swpm_sid: "{{ sap_swpm_inifile_sid.stdout }}" -- name: Display SAP SID +- name: SAP SWPM - Display SAP SID ansible.builtin.debug: msg: - "SAP SID {{ sap_swpm_sid }}" # Detect FQDN - name: SAP SWPM - Detect FQDN - ansible.builtin.shell: | - set -o pipefail && cat {{ sap_swpm_tmpdir.path }}/inifile.params | grep NW_getFQDN.FQDN | awk '{ print $3 }' + ansible.builtin.command: | + awk '!/^#/&&/NW_getFQDN.FQDN/{print $3}' {{ sap_swpm_tmpdir.path }}/inifile.params register: sap_swpm_inifile_fqdn changed_when: false # Set fact for FQDN -- name: Set FQDN +- name: SAP SWPM - Set FQDN ansible.builtin.set_fact: sap_swpm_fqdn: "{{ sap_swpm_inifile_fqdn.stdout }}" -- name: Display FQDN +- name: SAP SWPM - Display FQDN ansible.builtin.debug: msg: - "SAP fqdn {{ sap_swpm_fqdn }}" diff --git a/roles/sap_swpm/templates/configfile.j2 b/roles/sap_swpm/templates/configfile.j2 index a4148526e..e59f930b6 100644 --- a/roles/sap_swpm/templates/configfile.j2 +++ b/roles/sap_swpm/templates/configfile.j2 @@ -25,7 +25,7 @@ HDB_Software_Dialogs.useMediaCD = {{ sap_swpm_software_use_media }} ###### SAPINST.CD.PACKAGE.LANGUAGE = {{ sap_swpm_cd_language_path }} SAPINST.CD.PACKAGE.JAVA = {{ sap_swpm_cd_java_path }} -SAPINST.CD.PACKAGE.RDBMS = {{ sap_swpm_cd_rdms_path }} +SAPINST.CD.PACKAGE.RDBMS = {{ sap_swpm_cd_rdbms_path }} # SAPINST.CD.PACKAGE.KERNEL = # SAPINST.CD.PACKAGE.KERNEL2 = # SAPINST.CD.PACKAGE.KERNEL3 =