Skip to content

Commit c781a8b

Browse files
authored
Merge pull request #1082 from marcelmamula/sapcar_hana
sap_hana_install: Enhance SAPCAR detection functionality and handling of multiple files
2 parents 950adf2 + 1c98cf3 commit c781a8b

File tree

5 files changed

+173
-91
lines changed

5 files changed

+173
-91
lines changed

roles/sap_hana_install/tasks/pre_install.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@
174174
register: __sap_hana_install_register_find_directory_sap_hana_database_initial
175175
when: __sap_hana_install_register_stat_software_extract_directory.stat.exists
176176

177+
# All SAPCAR and SAR files pre_install steps will be skipped if role `sap_install_media_detect` successfully extracts software.
177178
- name: SAP HANA Pre Install - Set directory of 'hdblcm' from successful find result
178179
when:
179180
- __sap_hana_install_register_stat_software_extract_directory.stat.exists

roles/sap_hana_install/tasks/pre_install/hdblcm_prepare.yml

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,30 @@
3737
state: touch
3838
mode: '0755'
3939

40-
- name: SAP HANA hdblcm prepare - Prepare SAPCAR
41-
ansible.builtin.import_tasks: prepare_sapcar.yml
42-
tags:
43-
- sap_hana_install_prepare_sapcar
44-
- sap_hana_install_prepare_sarfiles
40+
# Ensure that temporary file __EXTRACTION_ONGOING__ is removed if fail occurs.
41+
- name: Rescue block for SAPCAR and SAR file preparation
42+
block:
43+
- name: SAP HANA hdblcm prepare - Prepare SAPCAR
44+
ansible.builtin.import_tasks: prepare_sapcar.yml
45+
tags:
46+
- sap_hana_install_prepare_sapcar
47+
- sap_hana_install_prepare_sarfiles
48+
49+
- name: SAP HANA hdblcm prepare - Prepare SAR files
50+
ansible.builtin.import_tasks: prepare_sarfiles.yml
51+
tags: sap_hana_install_prepare_sarfiles
52+
rescue:
53+
- name: SAP HANA hdblcm prepare - Remove status file '{{ sap_hana_install_software_extract_directory }}/__EXTRACTION_ONGOING__'
54+
ansible.builtin.file:
55+
path: "{{ sap_hana_install_software_extract_directory }}/__EXTRACTION_ONGOING__"
56+
state: absent
57+
58+
- name: SAP HANA hdblcm prepare - Preparation tasks failed
59+
ansible.builtin.fail:
60+
msg: |
61+
Preparation steps failed. Please see details of failed task above.
62+
Cleanup of temporary files was completed.
4563
46-
- name: SAP HANA hdblcm prepare - Prepare SAR files
47-
ansible.builtin.import_tasks: prepare_sarfiles.yml
48-
tags: sap_hana_install_prepare_sarfiles
4964
5065
- name: SAP HANA hdblcm prepare - Remove status file '{{ sap_hana_install_software_extract_directory }}/__EXTRACTION_ONGOING__'
5166
ansible.builtin.file:

roles/sap_hana_install/tasks/pre_install/prepare_sapcar.yml

Lines changed: 100 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
msg: "FAIL: The SAPCAR EXE file '{{ __sap_hana_install_fact_software_directory }}/{{ sap_hana_install_sapcar_filename }}' does not exist!"
1717
when: not __sap_hana_install_register_sapcar_stat.stat.exists
1818

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

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

70-
# We need the 'file' package for the 'file' command, which we need in the next task.
71-
# RHEL: The 'file' package is contained in the Base software group, which should be installed already.
72-
73-
# In the first step, we execute the file command for each of the SAPCAR EXE files. It displays the
74-
# hardware architecture in the second output field, using a string which is different from the output
75-
# of the 'uname -m' command. So we replace those strings by the "correct" ones. For ppc64 and ppc64le,
76-
# the second output field is identical. So in this case, we also look at the third and forth output field,
77-
# to handle cases where a ppc64 SAPCAR executable is present in the software directory.
78-
# After selecting the SAPCAR EXE files for the current architecture, we copy them to a temporary
79-
# directory sapcar_tmp in the software extract directory and then perform a checksum verification
80-
# for these files if the corresponding variable is set.
81-
- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Create directory '{{ sap_hana_install_software_extract_directory }}/sapcar_tmp'
70+
# Package 'file' is present in Base system, but this task ensures next task does not fail on hardened images.
71+
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Ensure file package is present
72+
ansible.builtin.package:
73+
name: file
74+
state: present
75+
76+
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Create directory '{{ sap_hana_install_software_extract_directory }}/sapcar_tmp'
8277
ansible.builtin.file:
8378
path: "{{ sap_hana_install_software_extract_directory }}/sapcar_tmp"
8479
state: directory
8580
mode: '0755'
8681

87-
# Reason for noqa: There are pipe symbols - as part of an or statement - in an awk command sequence.
88-
- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Identify matching SAR executables in '{{ __sap_hana_install_fact_software_directory }}' # noqa jinja[spacing]
89-
ansible.builtin.shell: |
90-
set -o pipefail &&
91-
for sapcar_any in SAPCAR*EXE; do
92-
file ${sapcar_any} | awk '{
93-
split ($0, a, ":"); split (a[2], b, ","); sub ("^ ", "", b[2]);
94-
sub ("x86-64", "x86_64", b[2]);
95-
if (index (b[2], "64-bit PowerPC") > 0) {
96-
if ((index (b[3], "GNU/Linux") > 0)||(index (b[4], "GNU/Linux") > 0)) {sub ("64-bit PowerPC", "ppc64le", b[2])};
97-
if ((index (b[3], "SYSV") > 0)||(index (b[4], "SYSV") > 0)) {sub ("64-bit PowerPC", "ppc64", b[2])};
98-
}
99-
sub ("IBM S/390", "s390x", b[2]);
100-
printf ("%s %s %s\n", a[1], b[2], b[3])}'
101-
done | awk '$2=="{{ ansible_architecture }}"{printf ("%s\n", $1)}'
82+
# In the first step, we execute the file command for each of the SAPCAR EXE files. It displays the
83+
# hardware architecture in the second output field, using a string which is different from the output
84+
# of the 'uname -m' command.
85+
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Find matching SAPCAR executables in '{{ __sap_hana_install_fact_software_directory }}'
86+
ansible.builtin.shell:
87+
cmd: set -o pipefail && find . -name 'SAPCAR*EXE' -exec file {} + | sed 's|^\./||'
10288
args:
10389
chdir: "{{ __sap_hana_install_fact_software_directory }}"
104-
register: __sap_hana_install_register_sapcar_matching_arch
105-
changed_when: no
90+
register: __sap_hana_install_register_sapcar_file_contents
91+
changed_when: false
10692

107-
- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Fail if no matching SAPCAR executable could be found
93+
# Loop through found files and compare them against search keywords for ansible_architecture.
94+
# Supported combinations are defined in the variable '__sap_hana_install_architecture_matrix' in vars/main.yml file.
95+
# Each platform can contain multiple search words. AND operator is achieved by counting all found keywords.
96+
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Compare found files against the variable ansible_architecture
97+
ansible.builtin.set_fact:
98+
__sap_hana_install_fact_sapcar_matching_arch: |
99+
{%- set matching_files = [] -%}
100+
{%- set rule_sets = __sap_hana_install_architecture_matrix.get(ansible_architecture, []) -%}
101+
{%- if rule_sets -%}
102+
{%- for line in __sap_hana_install_register_sapcar_file_contents.stdout_lines -%}
103+
{%- set parts = line.split(': ', 1) -%}
104+
{%- if parts | length > 1 -%}
105+
{%- set filename = parts[0] -%}
106+
{%- set file_info = parts[1] -%}
107+
108+
{# Create a list of boolean results for each rule set #}
109+
{%- set rule_results = [] -%}
110+
{%- for keyword_list in rule_sets -%}
111+
{%- set all_keywords_found = (keyword_list | select('in', file_info) | list | length) == (keyword_list | length) -%}
112+
{%- set _ = rule_results.append(all_keywords_found) -%}
113+
{%- endfor -%}
114+
115+
{%- if true in rule_results -%}
116+
{%- set _ = matching_files.append(filename) -%}
117+
{%- endif -%}
118+
{%- endif -%}
119+
{%- endfor -%}
120+
{%- endif -%}
121+
{{- matching_files -}}
122+
123+
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Fail if no matching SAPCAR executable could be found
108124
ansible.builtin.fail:
109125
msg: "FAIL: No SAPCAR EXE file for architecture '{{ ansible_architecture }}' was found in
110126
{{ __sap_hana_install_fact_software_directory }}!"
111-
when: __sap_hana_install_register_sapcar_matching_arch.stdout | length == 0
112-
113-
- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Create a list of files from SAPCAR executables of the matching architecture
114-
ansible.builtin.set_fact:
115-
__sap_hana_install_fact_sapcar_filenames_matching_arch: "{{ __sap_hana_install_fact_sapcar_filenames_matching_arch | d([]) + [item] }}"
116-
loop: "{{ __sap_hana_install_register_sapcar_matching_arch.stdout_lines }}"
127+
when: __sap_hana_install_fact_sapcar_matching_arch | length == 0
117128

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

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

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

150-
- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Display __sap_hana_install_fact_sapcar_dict
151-
ansible.builtin.debug:
152-
var: __sap_hana_install_fact_sapcar_dict
153-
154-
- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Verify checksum for SAPCAR executables
164+
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Verify checksum for SAPCAR executables
155165
ansible.builtin.include_tasks: verify_checksum.yml
156166
loop: "{{ __sap_hana_install_fact_sapcar_dict }}"
157167
loop_control:
@@ -160,31 +170,49 @@
160170
- __sap_hana_install_fact_sapcar_dict | length > 0
161171
- sap_hana_install_verify_checksums
162172

163-
# For each file in temporary directory sapcar_tmp in the software extract directory, we run it with option
164-
# --version and then identify the most recent one, which is then copied to directory sapcar.
165-
- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Identify the SAPCAR executable with the latest version
166-
ansible.builtin.shell: |
167-
set -o pipefail &&
168-
for sapcar_matching_arch in "{{ __sap_hana_install_fact_sapcar_filenames_matching_arch | map('quote') | join(' ') }}"; do
169-
( printf "%s " $(basename ${sapcar_matching_arch})
170-
{{ sap_hana_install_software_extract_directory }}/sapcar_tmp/$(basename ${sapcar_matching_arch}) --version |
171-
awk '/kernel release/{rel=$NF}/patch number/{printf ("%s %s\n", rel, $NF)}'
172-
)
173-
done | sort -k 2 -nr -k 3 -nr | awk 'NR==1{printf ("%s - SAP kernel: %s; Patch number: %s\n", $1, $2, $3)}'
173+
174+
# For each file in temporary directory sapcar_tmp in the software extract directory, we run it with option
175+
# --version and then identify the most recent one, which is then copied to directory sapcar.
176+
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Get version of all SAPCAR executable files
177+
ansible.builtin.command:
178+
cmd: "./{{ item }} --version"
174179
args:
175180
chdir: "{{ sap_hana_install_software_extract_directory }}/sapcar_tmp"
176-
register: __sap_hana_install_register_latest_sapcar_file
177-
changed_when: no
181+
loop: "{{ __sap_hana_install_fact_sapcar_matching_arch }}"
182+
register: __sap_hana_install_register_sapcar_versions
183+
ignore_errors: true
184+
changed_when: false
185+
186+
# Loop through found files and extract kernel and patch values before sorting them in descending order.
187+
# Resulting variable is used together with '| trim' to ensure that empty spaces are removed from shell command output.
188+
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Identify the SAPCAR executable with the latest version
189+
ansible.builtin.set_fact:
190+
__sap_hana_install_fact_latest_sapcar_file: |
191+
{%- set files_with_versions = [] -%}
192+
{%- for result in __sap_hana_install_register_sapcar_versions.results -%}
193+
{%- if not result.failed -%}
194+
{# Use regex to find the kernel and patch numbers, defaulting to 0 if not found #}
195+
{%- set kernel = result.stdout | regex_search('kernel release\s+(\d+)', '\\1') | first | default(0) | int -%}
196+
{%- set patch = result.stdout | regex_search('patch number\s+(\d+)', '\\1') | first | default(0) | int -%}
197+
198+
{# Append the structured data to our list #}
199+
{%- set _ = files_with_versions.append({'kernel': kernel, 'patch': patch, 'filename': result.item}) -%}
200+
{%- endif -%}
201+
{%- endfor -%}
202+
203+
{# Sort by patch (secondary) then by kernel (primary) in descending order and return first one #}
204+
{%- set sorted_files = files_with_versions | sort(attribute='patch', reverse=true) | sort(attribute='kernel', reverse=true) -%}
205+
{{- sorted_files[0].filename if sorted_files else 'none' -}}
206+
207+
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Set fact for SAPCAR executable from auto-detection
208+
ansible.builtin.set_fact:
209+
__sap_hana_install_fact_selected_sapcar_filename: "{{ __sap_hana_install_fact_latest_sapcar_file | trim }}"
178210

179-
- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Display SAPCAR executable file name, SAP kernel release, and patch number
211+
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Display SAPCAR executable file name
180212
ansible.builtin.debug:
181-
msg: "Using SAPCAR executable: {{ __sap_hana_install_register_latest_sapcar_file.stdout }}"
182-
183-
- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Set fact for SAPCAR executable from autodetection
184-
ansible.builtin.set_fact:
185-
__sap_hana_install_fact_selected_sapcar_filename: "{{ __sap_hana_install_register_latest_sapcar_file.stdout.split(' ').0 }}"
213+
msg: "Using SAPCAR executable: {{ __sap_hana_install_fact_selected_sapcar_filename }}"
186214

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

197-
- name: SAP HANA hdblcm prepare - SAPCAR autodetection - Remove directory '{{ sap_hana_install_software_extract_directory }}/sapcar_tmp'
225+
- name: SAP HANA hdblcm prepare - SAPCAR auto-detection - Remove directory '{{ sap_hana_install_software_extract_directory }}/sapcar_tmp'
198226
ansible.builtin.file:
199227
path: "{{ sap_hana_install_software_extract_directory }}/sapcar_tmp"
200228
state: absent

0 commit comments

Comments
 (0)