Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sap_*_preconfigure/Suse: Rework of preconfigure roles for Suse, add missing notes. #930

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion roles/sap_general_preconfigure/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ The IPV4 address to be used for updating or checking `/etc/hosts` entries.<br>
### sap_general_preconfigure_db_group_name
- _Type:_ `str`

Use this variable to specify the name of the RHEL group which is used for the database processes.<br>
(RedHat specific) Use this variable to specify the name of the RHEL group which is used for the database processes.<br>
If defined, it will be used to configure process limits as per step<br>
Configuring Process Resource Limits<br>

Expand Down
13 changes: 11 additions & 2 deletions roles/sap_general_preconfigure/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ sap_general_preconfigure_envgroups: "{{ __sap_general_preconfigure_envgroups }}"
# Example: See README.md

sap_general_preconfigure_packages: "{{ __sap_general_preconfigure_packages }}"
# The list of packages to install.
# The list of packages to be installed.
# The default for this variable is set in the vars file which corresponds to the detected OS version.

sap_general_preconfigure_min_package_check: true
Expand Down Expand Up @@ -164,11 +164,20 @@ sap_general_preconfigure_domain: "{{ sap_domain | d(ansible_domain) }}"
# The DNS domain name to be used for updating or checking `/etc/hosts` entries.

# sap_general_preconfigure_db_group_name: (not defined by default)
# Use this variable to specify the name of the RHEL group which is used for the database processes.
# (RedHat specific) Use this variable to specify the name of the RHEL group which is used for the database processes.
# If defined, it will be used to configure process limits as per step
# Configuring Process Resource Limits
# Example: See README.md

sap_general_preconfigure_run_grub2_mkconfig: true
# By default, the role will run `grub2-mkconfig` to update the Grub configuration if necessary.
# Set this parameter to `false` if this is not desired.

# (SUSE specific) Version of saptune to install.
# It is recommended to install latest version by keeping this variable empty.
# This will replace the current installed version if present, even downgrade if necessary.
sap_general_preconfigure_saptune_version: ''

# in SAP Note 2369910 SAP requires English locale
# If you want to define the locale set this to e.g. en_US.UTF-8
sap_general_preconfigure_default_locale: ""
Expand Down
104 changes: 94 additions & 10 deletions roles/sap_general_preconfigure/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -1,52 +1,136 @@
# SPDX-License-Identifier: Apache-2.0
---
# handlers file for sap_general_preconfigure

# BEGIN - GRUB section
- name: "Check if server is booted in BIOS or UEFI mode"
ansible.builtin.stat:
path: /sys/firmware/efi
get_checksum: false
register: __sap_general_preconfigure_register_stat_sys_firmware_efi
listen: __sap_general_preconfigure_regenerate_grub2_conf_handler
when:
- sap_general_preconfigure_run_grub2_mkconfig | d(true)

- name: Debug BIOS or UEFI
ansible.builtin.debug:
var: __sap_general_preconfigure_register_stat_sys_firmware_efi.stat.exists
listen: __sap_general_preconfigure_regenerate_grub2_conf_handler
when:
- sap_general_preconfigure_run_grub2_mkconfig | d(true)

- name: "Run grub-mkconfig (BIOS mode)"
ansible.builtin.command:
cmd: grub2-mkconfig -o /boot/grub2/grub.cfg
register: __sap_general_preconfigure_register_grub2_mkconfig_bios_mode
changed_when: true
listen: __sap_general_preconfigure_regenerate_grub2_conf_handler
notify: __sap_general_preconfigure_reboot_handler
when:
- not __sap_general_preconfigure_register_stat_sys_firmware_efi.stat.exists
- sap_general_preconfigure_run_grub2_mkconfig | d(true)

- name: "Debug grub-mkconfig BIOS mode"
ansible.builtin.debug:
var: __sap_general_preconfigure_register_grub2_mkconfig_bios_mode.stdout_lines,
__sap_general_preconfigure_register_grub2_mkconfig_bios_mode.stderr_lines
listen: __sap_general_preconfigure_regenerate_grub2_conf_handler
when:
- not __sap_general_preconfigure_register_stat_sys_firmware_efi.stat.exists
- sap_general_preconfigure_run_grub2_mkconfig | d(true)

- name: "Set the grub.cfg location RHEL"
ansible.builtin.set_fact:
__sap_general_preconfigure_uefi_boot_dir: /boot/efi/EFI/redhat/grub.cfg
listen: __sap_general_preconfigure_regenerate_grub2_conf_handler
when:
- ansible_distribution == 'RedHat'

- name: "Set the grub.cfg location SLES"
ansible.builtin.set_fact:
__sap_general_preconfigure_uefi_boot_dir: /boot/efi/EFI/BOOT/grub.cfg
listen: __sap_general_preconfigure_regenerate_grub2_conf_handler
when:
- ansible_distribution == 'SLES' or ansible_distribution == 'SLES_SAP'

- name: "Run grub-mkconfig (UEFI mode)"
ansible.builtin.command:
cmd: "grub2-mkconfig -o {{ __sap_general_preconfigure_uefi_boot_dir }}"
register: __sap_general_preconfigure_register_grub2_mkconfig_uefi_mode
changed_when: true
listen: __sap_general_preconfigure_regenerate_grub2_conf_handler
notify: __sap_general_preconfigure_reboot_handler
when:
- __sap_general_preconfigure_register_stat_sys_firmware_efi.stat.exists
- sap_general_preconfigure_run_grub2_mkconfig | d(true)

- name: "Debug grub-mkconfig UEFI"
ansible.builtin.debug:
var: __sap_general_preconfigure_register_grub2_mkconfig_uefi_mode.stdout_lines,
__sap_general_preconfigure_register_grub2_mkconfig_uefi_mode.stderr_lines
listen: __sap_general_preconfigure_regenerate_grub2_conf_handler
when:
- __sap_general_preconfigure_register_stat_sys_firmware_efi.stat.exists
- sap_general_preconfigure_run_grub2_mkconfig | d(true)

# END - GRUB section


- name: Reboot the managed node
ansible.builtin.reboot:
test_command: /bin/true
listen: __sap_general_preconfigure_reboot_handler
when:
- sap_general_preconfigure_reboot_ok|d(false)
- sap_general_preconfigure_reboot_ok | d(false)


# Kernel update triggers zypper purge-kernels and lock after reboot.
- name: Wait for Zypper lock to be released
ansible.builtin.command:
cmd: zypper info zypper
retries: 60
timeout: 5
retries: 20
timeout: 30
listen: __sap_general_preconfigure_reboot_handler
when:
- ansible_os_family == 'Suse'
- sap_general_preconfigure_reboot_ok | d(false)
changed_when: false


- name: Let the role fail if a reboot is required
ansible.builtin.fail:
msg: Reboot is required!
listen: __sap_general_preconfigure_reboot_handler
when:
- sap_general_preconfigure_fail_if_reboot_required|d(true)
- not sap_general_preconfigure_reboot_ok|d(false)
- sap_general_preconfigure_fail_if_reboot_required | d(true)
- not sap_general_preconfigure_reboot_ok | d(false)

- name: Show a warning message if a reboot is required
ansible.builtin.debug:
msg: "WARN: Reboot is required!"
listen: __sap_general_preconfigure_reboot_handler
when:
- not sap_general_preconfigure_fail_if_reboot_required|d(true)
- not sap_general_preconfigure_reboot_ok|d(false)
- not sap_general_preconfigure_fail_if_reboot_required | d(true)
- not sap_general_preconfigure_reboot_ok | d(false)

- name: Unmask packagekit.service
ansible.builtin.systemd_service:
name: packagekit.service
masked: false
listen: __sap_general_preconfigure_packagekit_handler


# Reasons for noqa:
# - command-instead-of-module: We want to avoid non-ansible.builtin modules where possible
# - no-changed-when: Remounting does not do any harm and does not affect idempotency.
- name: Remount /dev/shm # noqa command-instead-of-module no-changed-when
ansible.builtin.command: mount -o remount /dev/shm
ansible.builtin.command:
cmd: mount -o remount /dev/shm
listen: __sap_general_preconfigure_mount_tmpfs_handler
tags: molecule-idempotence-notest

- name: Check if /dev/shm is available
ansible.builtin.command: df -h /dev/shm
ansible.builtin.command:
cmd: df -h /dev/shm
register: __sap_general_preconfigure_command_df_shm_result
changed_when: false
listen: __sap_general_preconfigure_mount_tmpfs_handler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@

- name: Assert - Include configuration actions for required sapnotes
ansible.builtin.include_tasks: "sapnote/assert-{{ sap_note_line_item.number }}.yml"
with_items: "{{ __sap_general_preconfigure_sapnotes_versions | difference(['']) }}"
loop: "{{ __sap_general_preconfigure_sapnotes_versions | difference(['']) }}"
loop_control:
loop_var: sap_note_line_item
160 changes: 53 additions & 107 deletions roles/sap_general_preconfigure/tasks/SLES/assert-installation.yml
Original file line number Diff line number Diff line change
@@ -1,96 +1,57 @@
# SPDX-License-Identifier: Apache-2.0
---

- name: Get list of what provides packages # noqa command-instead-of-module
ansible.builtin.command:
cmd: "rpm -q --whatprovides {{ item }}"
register: __sap_general_preconfigure_register_whatprovides
changed_when: false
ignore_errors: true
loop: "{{ sap_general_preconfigure_packages }}"


# Both sap_general_preconfigure_packages and __sap_general_preconfigure_min_pkgs are checked at same time.
- name: Assert that all required packages are installed
ansible.builtin.assert:
that: line_item in ansible_facts.packages
fail_msg: "FAIL: Package '{{ line_item }}' is not installed!"
success_msg: "PASS: Package '{{ line_item }}' is installed."
with_items:
- "{{ sap_general_preconfigure_packages }}"
loop_control:
loop_var: line_item
that: item in ansible_facts.packages
or __sap_general_preconfigure_register_whatprovides.results | selectattr('item', 'equalto', item) | map(attribute='rc') | first == 0
fail_msg: "FAIL: Package '{{ item }}' is not installed!"
success_msg: "PASS: Package '{{ item }}' is installed."
loop: "{{ sap_general_preconfigure_packages if not sap_general_preconfigure_min_package_check | bool
else ((sap_general_preconfigure_packages | d([])) + (__sap_general_preconfigure_min_pkgs | d([])) | map(attribute='0') | unique) }}"
ignore_errors: "{{ sap_general_preconfigure_assert_ignore_errors | d(false) }}"

- name: Minimum required package version check

# Availability of minimum packages is checked above.
- name: Assert that all minimum required packages are installed with minimum version
ansible.builtin.assert:
that:
- __version is version(item[1], '>=')
fail_msg: "FAIL: Minimum package version '{{ item[0] }}-{{ item[1] }}' is not installed! Current version: '{{ __version }}'"
success_msg: "PASS: Minimum package version '{{ item[0] }}-{{ item[1] }}' is installed."
vars:
__version: "{{ ansible_facts.packages[item[0]][0]['version'] ~ '-' ~ ansible_facts.packages[item[0]][0]['release']
~ '.' ~ ansible_facts.packages[item[0]][0]['arch']}}"
loop: "{{ __sap_general_preconfigure_min_pkgs }}"
when:
- sap_general_preconfigure_min_package_check | bool
- __sap_general_preconfigure_min_pkgs | d([])
block:

# Reason for noqa: We can safely fail at the last command in the pipeline.
- name: Assert - Create a list of minimum required package versions to be installed # noqa risky-shell-pipe
# How does it work?
# 1 - Print the required package name and version with a prefix "1" followed by a space.
# 2 - In the same output sequence, list all installed versions of this package with a prefix "2" followed by a space.
# 3 - Replace all occurrences of ".el" by ".0.0" so that the sort -V correctly sorts packages with ".el" in its name
# 4 - Sort the list by the name and version.
# 5 - Replace ".0.0" by ".el" again to get back the original names.
# 6 - Store the last installed version of the package in variable latestpkg.
# 7 - Store the last content of column 1 in variable col1, the last content of column 2 in variable col2,
# and the last number of fields in variable _nf.
# 8 - case 1: If the last number of output fields is greater than 2, it indicates that the package is not installed
# because the output of "rpm -q" will be similar to "package XXX is not installed".
# 8 - case 2a: If the first column of the last line of the output is "1", it means that the required package is
# the latest of all required and installed versions of the package, so it means that the package needs
# to be updated.
# 8 - case 2b: If the first column of the last line of the output is "2", it means that at least of the installed
# versions the package is equal to or greater than the required package version.
ansible.builtin.shell: |
(echo "1 {{ pkg[0] }}-{{ pkg[1] }}";rpm -q --qf "%{NAME}-%{VERSION}-%{RELEASE}\n" {{ pkg[0] }} |
awk '{printf ("2 %s\n", $0)}') |
awk '{gsub ("\\.el", ".0.0"); print}' |
sort -k 2 -k 1 -V |
awk '{gsub ("\\.0\\.0", ".el"); col1=$1; col2=$2; _nf=NF}
$1==2{latestpkg=$2}
END {
if (_nf>2) {
printf ("Package '\''{{ pkg[0] }}'\'' needs to be installed as {{ pkg[0] }}-{{ pkg[1] }}!\n")
} else {
if (col1==1) {
printf ("Package '\''{{ pkg[0] }}'\'' needs to be updated to %s! Currently installed latest version: %s.\n", $2, latestpkg)
}
if (col1==2) {
printf ("Package '\''{{ pkg[0] }}'\'' is already installed as {{ pkg[0] }}-{{ pkg[1] }} or later. Currently installed latest version: %s.\n", latestpkg)
}
}
}'
with_list: "{{ __sap_general_preconfigure_min_pkgs }}"
loop_control:
loop_var: pkg
check_mode: false
register: __sap_general_preconfigure_register_minpkglist_assert
changed_when: false

- name: Assert that minimum required package versions are installed
# If the output includes the string "is already installed" (case 2b), we have a PASS. Otherwise, it's a FAIL.
ansible.builtin.assert:
that: "'is already installed' in line_item.stdout"
fail_msg: "FAIL: {{ line_item.stdout }}"
success_msg: "PASS: {{ line_item.stdout }}"
with_items: "{{ __sap_general_preconfigure_register_minpkglist_assert.results }}"
loop_control:
loop_var: line_item
label: ""
ignore_errors: true
ignore_errors: "{{ sap_general_preconfigure_assert_ignore_errors | d(false) }}"

- name: Report if no minimum required package version is defined for this RHEL release
ansible.builtin.debug:
msg: "INFO: No minimum required package version defined (variable __sap_general_preconfigure_min_pkgs)."
ignore_errors: true
when: not __sap_general_preconfigure_min_pkgs | d([])

# Reason for noqa: The yum module appears to not support the check-update option
- name: Get info about possible package updates # noqa command-instead-of-module
ansible.builtin.command: yum check-update
register: __sap_general_preconfigure_register_yum_check_update_assert
ansible.builtin.command:
cmd: zypper -q patch-check
timeout: 120
retries: 5
register: __sap_general_preconfigure_register_zypper_check_update_assert
changed_when: false
ignore_errors: "{{ sap_general_preconfigure_assert_ignore_errors | d(false) }}"
ignore_errors: true # true, because unpatched system is always error.
when: sap_general_preconfigure_update

- name: Assert that there are no more possible package updates
ansible.builtin.assert:
that: __sap_general_preconfigure_register_yum_check_update_assert is success
that: __sap_general_preconfigure_register_zypper_check_update_assert.rc == 0
fail_msg: "FAIL: System needs to be updated!"
success_msg: "PASS: There are no more outstanding package updates."
ignore_errors: "{{ sap_general_preconfigure_assert_ignore_errors | d(false) }}"
Expand All @@ -99,49 +60,34 @@
- name: Report if checking for possible package updates is not requested
ansible.builtin.debug:
msg: "INFO: Not checking for possible package updates (variable sap_general_preconfigure_update)."
ignore_errors: true
ignore_errors: "{{ sap_general_preconfigure_assert_ignore_errors | d(false) }}"
when: not sap_general_preconfigure_update

- name: "Assert - Set needs-restarting command in case of RHEL 7"
ansible.builtin.set_fact:
__sap_general_preconfigure_fact_needs_restarting_command_assert: "needs-restarting -r"
when:
- ansible_os_family == 'RedHat'
- ansible_distribution_major_version == '7'

- name: "Assert - Set needs-restarting command in case of RHEL 8 or RHEL 9, except RHEL 8.0"
ansible.builtin.set_fact:
__sap_general_preconfigure_fact_needs_restarting_command_assert: "yum needs-restarting -r"
when:
- ansible_os_family == 'RedHat'
- (ansible_distribution_major_version == '8' or
ansible_distribution_major_version == '9'
)
- ansible_distribution_version != '8.0'

- name: "Assert - Set customized needs-restarting command in case of RHEL 8.0"
ansible.builtin.set_fact:
__sap_general_preconfigure_fact_needs_restarting_command_assert: "_IKRNL=$(rpm -q --last kernel | awk 'NR==1{sub(/kernel-/,\"\"); print $1}');
_CKRNL=$(uname -r); if [ ${_IKRNL} != ${_CKRNL} ]; then exit 1; else exit 0; fi"
when:
- ansible_os_family == 'RedHat'
- ansible_distribution_version == '8.0'

- name: Assert - Display the command for checking a reboot requirement
ansible.builtin.debug:
var: __sap_general_preconfigure_fact_needs_restarting_command_assert

# Reason for noqa: The command to be executed might contain pipes
- name: Assert - Determine if the system needs to be restarted # noqa command-instead-of-shell
ansible.builtin.shell: "{{ __sap_general_preconfigure_fact_needs_restarting_command_assert }}"
- name: Determine if the system needs to be restarted # noqa command-instead-of-shell
ansible.builtin.shell:
cmd: "zypper ps"
register: __sap_general_preconfigure_register_needs_restarting_assert
changed_when: false
check_mode: false
ignore_errors: "{{ sap_general_preconfigure_assert_ignore_errors | d(false) }}"
ignore_errors: true # true, because output is too large.

- name: Assert that system needs no restart
ansible.builtin.assert:
that: __sap_general_preconfigure_register_needs_restarting_assert is success
fail_msg: "FAIL: System needs to be restarted!"
success_msg: "PASS: System needs no restart."
ignore_errors: "{{ sap_general_preconfigure_assert_ignore_errors | d(false) }}"


- name: Assert saptune is at requested version
ansible.builtin.assert:
that: ansible_facts.packages['saptune'][0]['version'] == sap_general_preconfigure_saptune_version
fail_msg: "FAIL: saptune version installed is {{ ansible_facts.packages['saptune'][0]['version']
}} but the version {{ sap_general_preconfigure_saptune_version }} was expected"
success_msg: "PASS: the installed version of saptune meets the expected version: {{ sap_general_preconfigure_saptune_version }}"
when:
- __sap_general_preconfigure_use_saptune
- sap_general_preconfigure_saptune_version is defined
- sap_general_preconfigure_saptune_version | length > 0
Loading
Loading