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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions roles/sap_hana_install/tasks/pre_install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@
register: __sap_hana_install_register_find_directory_sap_hana_database_initial
when: __sap_hana_install_register_stat_software_extract_directory.stat.exists

# All SAPCAR and SAR files pre_install steps will be skipped if role `sap_install_media_detect` successfully extracts software.
- name: SAP HANA Pre Install - Set directory of 'hdblcm' from successful find result
when:
- __sap_hana_install_register_stat_software_extract_directory.stat.exists
Expand Down
31 changes: 23 additions & 8 deletions roles/sap_hana_install/tasks/pre_install/hdblcm_prepare.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,30 @@
state: touch
mode: '0755'

- name: SAP HANA hdblcm prepare - Prepare SAPCAR
ansible.builtin.import_tasks: prepare_sapcar.yml
tags:
- sap_hana_install_prepare_sapcar
- sap_hana_install_prepare_sarfiles
# Ensure that temporary file __EXTRACTION_ONGOING__ is removed if fail occurs.
- name: Rescue block for SAPCAR and SAR file preparation
block:
- name: SAP HANA hdblcm prepare - Prepare SAPCAR
ansible.builtin.import_tasks: prepare_sapcar.yml
tags:
- sap_hana_install_prepare_sapcar
- sap_hana_install_prepare_sarfiles

- name: SAP HANA hdblcm prepare - Prepare SAR files
ansible.builtin.import_tasks: prepare_sarfiles.yml
tags: sap_hana_install_prepare_sarfiles
rescue:
- name: SAP HANA hdblcm prepare - Remove status file '{{ sap_hana_install_software_extract_directory }}/__EXTRACTION_ONGOING__'
ansible.builtin.file:
path: "{{ sap_hana_install_software_extract_directory }}/__EXTRACTION_ONGOING__"
state: absent

- name: SAP HANA hdblcm prepare - Preparation tasks failed
ansible.builtin.fail:
msg: |
Preparation steps failed. Please see details of failed task above.
Cleanup of temporary files was completed.

- name: SAP HANA hdblcm prepare - Prepare SAR files
ansible.builtin.import_tasks: prepare_sarfiles.yml
tags: sap_hana_install_prepare_sarfiles

- name: SAP HANA hdblcm prepare - Remove status file '{{ sap_hana_install_software_extract_directory }}/__EXTRACTION_ONGOING__'
ansible.builtin.file:
Expand Down
172 changes: 100 additions & 72 deletions roles/sap_hana_install/tasks/pre_install/prepare_sapcar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
msg: "FAIL: The SAPCAR EXE file '{{ __sap_hana_install_fact_software_directory }}/{{ sap_hana_install_sapcar_filename }}' does not exist!"
when: not __sap_hana_install_register_sapcar_stat.stat.exists

# We cannot always use the SAPCAR executable in __sap_hana_install_fact_software_directory because there are
# some configurations in which executing files in this directory is not possible. So we always copy SAPCAR
# to directory 'sapcar' in sap_hana_install_software_extract_directory. We do not copy the SAPCAR checksum file.
# We cannot always use the SAPCAR executable in __sap_hana_install_fact_software_directory because there are
# some configurations in which executing files in this directory is not possible. So we always copy SAPCAR
# to directory 'sapcar' in sap_hana_install_software_extract_directory. We do not copy the SAPCAR checksum file.
- name: SAP HANA hdblcm prepare - SAPCAR defined - Copy the SAPCAR executable to '{{ sap_hana_install_software_extract_directory }}/sapcar'
ansible.builtin.copy:
src: "{{ __sap_hana_install_fact_software_directory }}/{{ sap_hana_install_sapcar_filename }}"
Expand Down Expand Up @@ -63,95 +63,105 @@
ansible.builtin.set_fact:
__sap_hana_install_fact_selected_sapcar_filename: "{{ sap_hana_install_sapcar_filename }}"

- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Prepare the SAPCAR executable if 'sap_hana_install_sapcar_filename' is not defined
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Prepare the SAPCAR executable if 'sap_hana_install_sapcar_filename' is not defined
when: sap_hana_install_sapcar_filename is not defined
block:

# We need the 'file' package for the 'file' command, which we need in the next task.
# RHEL: The 'file' package is contained in the Base software group, which should be installed already.

# In the first step, we execute the file command for each of the SAPCAR EXE files. It displays the
# hardware architecture in the second output field, using a string which is different from the output
# of the 'uname -m' command. So we replace those strings by the "correct" ones. For ppc64 and ppc64le,
# the second output field is identical. So in this case, we also look at the third and forth output field,
# to handle cases where a ppc64 SAPCAR executable is present in the software directory.
# After selecting the SAPCAR EXE files for the current architecture, we copy them to a temporary
# directory sapcar_tmp in the software extract directory and then perform a checksum verification
# for these files if the corresponding variable is set.
- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Create directory '{{ sap_hana_install_software_extract_directory }}/sapcar_tmp'
# Package 'file' is present in Base system, but this task ensures next task does not fail on hardened images.
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Ensure file package is present
ansible.builtin.package:
name: file
state: present

- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Create directory '{{ sap_hana_install_software_extract_directory }}/sapcar_tmp'
ansible.builtin.file:
path: "{{ sap_hana_install_software_extract_directory }}/sapcar_tmp"
state: directory
mode: '0755'

# Reason for noqa: There are pipe symbols - as part of an or statement - in an awk command sequence.
- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Identify matching SAR executables in '{{ __sap_hana_install_fact_software_directory }}' # noqa jinja[spacing]
ansible.builtin.shell: |
set -o pipefail &&
for sapcar_any in SAPCAR*EXE; 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 '$2=="{{ ansible_architecture }}"{printf ("%s\n", $1)}'
# In the first step, we execute the file command for each of the SAPCAR EXE files. It displays the
# hardware architecture in the second output field, using a string which is different from the output
# of the 'uname -m' command.
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Find matching SAPCAR executables in '{{ __sap_hana_install_fact_software_directory }}'
ansible.builtin.shell:
cmd: set -o pipefail && find . -name 'SAPCAR*EXE' -exec file {} + | sed 's|^\./||'
args:
chdir: "{{ __sap_hana_install_fact_software_directory }}"
register: __sap_hana_install_register_sapcar_matching_arch
changed_when: no
register: __sap_hana_install_register_sapcar_file_contents
changed_when: false

- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Fail if no matching SAPCAR executable could be found
# Loop through found files and compare them against search keywords for ansible_architecture.
# Supported combinations are defined in the variable '__sap_hana_install_architecture_matrix' in vars/main.yml file.
# Each platform can contain multiple search words. AND operator is achieved by counting all found keywords.
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Compare found files against the variable ansible_architecture
ansible.builtin.set_fact:
__sap_hana_install_fact_sapcar_matching_arch: |
{%- set matching_files = [] -%}
{%- set rule_sets = __sap_hana_install_architecture_matrix.get(ansible_architecture, []) -%}
{%- if rule_sets -%}
{%- for line in __sap_hana_install_register_sapcar_file_contents.stdout_lines -%}
{%- set parts = line.split(': ', 1) -%}
{%- if parts | length > 1 -%}
{%- set filename = parts[0] -%}
{%- set file_info = parts[1] -%}

{# Create a list of boolean results for each rule set #}
{%- set rule_results = [] -%}
{%- for keyword_list in rule_sets -%}
{%- set all_keywords_found = (keyword_list | select('in', file_info) | list | length) == (keyword_list | length) -%}
{%- set _ = rule_results.append(all_keywords_found) -%}
{%- endfor -%}

{%- if true in rule_results -%}
{%- set _ = matching_files.append(filename) -%}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
{%- endif -%}
{{- matching_files -}}

- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Fail if no matching SAPCAR executable could be found
ansible.builtin.fail:
msg: "FAIL: No SAPCAR EXE file for architecture '{{ ansible_architecture }}' was found in
{{ __sap_hana_install_fact_software_directory }}!"
when: __sap_hana_install_register_sapcar_matching_arch.stdout | length == 0

- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Create a list of files from SAPCAR executables of the matching architecture
ansible.builtin.set_fact:
__sap_hana_install_fact_sapcar_filenames_matching_arch: "{{ __sap_hana_install_fact_sapcar_filenames_matching_arch | d([]) + [item] }}"
loop: "{{ __sap_hana_install_register_sapcar_matching_arch.stdout_lines }}"
when: __sap_hana_install_fact_sapcar_matching_arch | length == 0

- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Copy matching SAPCAR executables to '{{ sap_hana_install_software_extract_directory }}/sapcar_tmp/'
# After selecting the SAPCAR EXE files for the current architecture, we copy them to a temporary
# directory sapcar_tmp in the software extract directory and then perform a checksum verification
# for these files if the corresponding variable is set.
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Copy matching SAPCAR executables to '{{ sap_hana_install_software_extract_directory }}/sapcar_tmp/'
ansible.builtin.copy:
src: "{{ __sap_hana_install_fact_software_directory }}/{{ item }}"
dest: "{{ sap_hana_install_software_extract_directory }}/sapcar_tmp/{{ item }}"
remote_src: true
owner: 'root'
group: 'root'
mode: '0755'
with_items: "{{ __sap_hana_install_fact_sapcar_filenames_matching_arch }}"
loop: "{{ __sap_hana_install_fact_sapcar_matching_arch }}"

- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Fill list of dicts containing dir, file, and global checksum file
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Fill list of dicts containing dir, file, and global checksum file
ansible.builtin.set_fact:
__sap_hana_install_fact_sapcar_dict: "{{ __sap_hana_install_fact_sapcar_dict | d([]) + [__sap_hana_install_tmp_sapcar_dict] }}"
with_items: "{{ __sap_hana_install_fact_sapcar_filenames_matching_arch }}"
loop: "{{ __sap_hana_install_fact_sapcar_matching_arch }}"
vars:
__sap_hana_install_tmp_sapcar_dict:
dir: "{{ sap_hana_install_software_extract_directory }}/sapcar_tmp"
file: "{{ item }}"
checksum_file: "{{ sap_hana_install_global_checksum_file }}"
when: sap_hana_install_global_checksum_file is defined

- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Fill list of dicts containing dir, file, and specific checksum file
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Fill list of dicts containing dir, file, and specific checksum file
ansible.builtin.set_fact:
__sap_hana_install_fact_sapcar_dict: "{{ __sap_hana_install_fact_sapcar_dict | d([]) + [__sap_hana_install_tmp_sapcar_dict] }}"
with_items: "{{ __sap_hana_install_fact_sapcar_filenames_matching_arch }}"
loop: "{{ __sap_hana_install_fact_sapcar_matching_arch }}"
vars:
__sap_hana_install_tmp_sapcar_dict:
dir: "{{ sap_hana_install_software_extract_directory }}/sapcar_tmp"
file: "{{ item }}"
checksum_file: "{{ __sap_hana_install_fact_software_directory }}/{{ item }}.sha256"
when: sap_hana_install_global_checksum_file is not defined

- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Display __sap_hana_install_fact_sapcar_dict
ansible.builtin.debug:
var: __sap_hana_install_fact_sapcar_dict

- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Verify checksum for SAPCAR executables
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Verify checksum for SAPCAR executables
ansible.builtin.include_tasks: verify_checksum.yml
loop: "{{ __sap_hana_install_fact_sapcar_dict }}"
loop_control:
Expand All @@ -160,31 +170,49 @@
- __sap_hana_install_fact_sapcar_dict | length > 0
- sap_hana_install_verify_checksums

# For each file in temporary directory sapcar_tmp in the software extract directory, we run it with option
# --version and then identify the most recent one, which is then copied to directory sapcar.
- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Identify the SAPCAR executable with the latest version
ansible.builtin.shell: |
set -o pipefail &&
for sapcar_matching_arch in "{{ __sap_hana_install_fact_sapcar_filenames_matching_arch | map('quote') | join(' ') }}"; do
( printf "%s " $(basename ${sapcar_matching_arch})
{{ sap_hana_install_software_extract_directory }}/sapcar_tmp/$(basename ${sapcar_matching_arch}) --version |
awk '/kernel release/{rel=$NF}/patch number/{printf ("%s %s\n", rel, $NF)}'
)
done | sort -k 2 -nr -k 3 -nr | awk 'NR==1{printf ("%s - SAP kernel: %s; Patch number: %s\n", $1, $2, $3)}'

# For each file in temporary directory sapcar_tmp in the software extract directory, we run it with option
# --version and then identify the most recent one, which is then copied to directory sapcar.
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Get version of all SAPCAR executable files
ansible.builtin.command:
cmd: "./{{ item }} --version"
args:
chdir: "{{ sap_hana_install_software_extract_directory }}/sapcar_tmp"
register: __sap_hana_install_register_latest_sapcar_file
changed_when: no
loop: "{{ __sap_hana_install_fact_sapcar_matching_arch }}"
register: __sap_hana_install_register_sapcar_versions
ignore_errors: true
changed_when: false

# Loop through found files and extract kernel and patch values before sorting them in descending order.
# Resulting variable is used together with '| trim' to ensure that empty spaces are removed from shell command output.
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Identify the SAPCAR executable with the latest version
ansible.builtin.set_fact:
__sap_hana_install_fact_latest_sapcar_file: |
{%- set files_with_versions = [] -%}
{%- for result in __sap_hana_install_register_sapcar_versions.results -%}
{%- if not result.failed -%}
{# Use regex to find the kernel and patch numbers, defaulting to 0 if not found #}
{%- set kernel = result.stdout | regex_search('kernel release\s+(\d+)', '\\1') | first | default(0) | int -%}
{%- set patch = result.stdout | regex_search('patch number\s+(\d+)', '\\1') | first | default(0) | int -%}

{# Append the structured data to our list #}
{%- set _ = files_with_versions.append({'kernel': kernel, 'patch': patch, 'filename': result.item}) -%}
{%- endif -%}
{%- endfor -%}

{# Sort by patch (secondary) then by kernel (primary) in descending order and return first one #}
{%- set sorted_files = files_with_versions | sort(attribute='patch', reverse=true) | sort(attribute='kernel', reverse=true) -%}
{{- sorted_files[0].filename if sorted_files else 'none' -}}

- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Set fact for SAPCAR executable from auto-detection
ansible.builtin.set_fact:
__sap_hana_install_fact_selected_sapcar_filename: "{{ __sap_hana_install_fact_latest_sapcar_file | trim }}"

- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Display SAPCAR executable file name, SAP kernel release, and patch number
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Display SAPCAR executable file name
ansible.builtin.debug:
msg: "Using SAPCAR executable: {{ __sap_hana_install_register_latest_sapcar_file.stdout }}"

- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Set fact for SAPCAR executable from autodetection
ansible.builtin.set_fact:
__sap_hana_install_fact_selected_sapcar_filename: "{{ __sap_hana_install_register_latest_sapcar_file.stdout.split(' ').0 }}"
msg: "Using SAPCAR executable: {{ __sap_hana_install_fact_selected_sapcar_filename }}"

- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Copy the autodetected SAPCAR executable to '{{ sap_hana_install_software_extract_directory }}/sapcar'
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Copy the autodetected SAPCAR executable to '{{ sap_hana_install_software_extract_directory }}/sapcar'
ansible.builtin.copy:
src: "{{ sap_hana_install_software_extract_directory }}/sapcar_tmp/{{ __sap_hana_install_fact_selected_sapcar_filename }}"
dest: "{{ sap_hana_install_software_extract_directory }}/sapcar/{{ __sap_hana_install_fact_selected_sapcar_filename }}"
Expand All @@ -194,7 +222,7 @@
mode: '0755'
when: not ansible_check_mode

- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Remove directory '{{ sap_hana_install_software_extract_directory }}/sapcar_tmp'
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Remove directory '{{ sap_hana_install_software_extract_directory }}/sapcar_tmp'
ansible.builtin.file:
path: "{{ sap_hana_install_software_extract_directory }}/sapcar_tmp"
state: absent
Expand Down
Loading