qe-sap-deployment test lib
Copyright 2025 SUSE LLC
SPDX-License-Identifier: FSFAP
QE SAP <qe-sap@suse.de>
Package with common methods and default or constant values for qe-sap-deployment
Returns a hash containing file paths for configuration files
Create all needed folders
Scans yaml configuration for '%OPENQA_VARIABLE%' placeholders and
searches for values in OpenQA defined variables.
Returns hash with openqa variable key/value pairs.
Writes "ansible" section into yaml configuration file.
$args{ansible_section} defines section(key) name.
$args{section_content} defines content of names section.
Example:
@playbook_list = ("pre-cluster.yaml", "cluster_sbd_prep.yaml");
qesap_create_ansible_section(ansible_section=>'create', section_content=>\@playbook_list);
Run a command within the Python virtualenv
created by qesap_pip_install.
This function never dies: it always returns an error to the caller.
Timeout error is 124 (the one reported by timeout command line utility).
Return string of the python to use
Return string of the pip to use
Install all Python requirements of the qe-sap-deployment
in a dedicated virtual environment.
This function has no return code but it is expected to die
if something internally fails.
Install all Ansible requirements of the qe-sap-deployment.
This function has no return code but it is expected to die
if something internally fails.
qesap_upload_logs([failok=1])
Collect and upload logs present in @log_files.
This is about logs generated locally on the jumphost.
Get the qe-sap-deployment code
Keep in mind that to allow qe-sap-deployment to use roles from this repo,
your config.yaml has to have a specific setting ansible::roles_path.
Replaces yaml configuration file variables with parameters
defined by OpenQA test code, yaml template or yaml schedule.
Openqa variables need to be added as a hash
with key/value pair inside %run_args{openqa_variables}.
Example:
my %variables;
$variables{HANA_SAR} = get_required_var("HANA_SAR");
$variables{HANA_CLIENT_SAR} = get_required_var("HANA_CLIENT_SAR");
qesap_yaml_replace(openqa_variables=>\%variables);
qesap_execute(
cmd => '<configure|terraform,|ansible>',
logname => '<SOMENAME>.log.txt'
[, verbose => 1, cmd_options => <cmd_options>] );
Example:
qesap_execute(cmd => 'terraform', logname => 'terraform_destroy.log.txt', cmd_options => '-d')
result in:
qesap.py terraform -d
Execute qesap glue script commands. Check project documentation for available options:
https://github.com/SUSE/qe-sap-deployment
Function returns a two element array:
- first element is an integer representing the execution result
- second element is the file path of the execution log
This function is not expected to internally die, any failure has to be handled by the caller.
qesap_terraform_conditional_retry(
error_list => ['Fatal:'],
logname => 'somefile.txt'
[, verbose => 1, cmd_options => '--parallel 3', timeout => 1200, retries => 5, destroy => 1, delay_sec => 6, random_factor => 0.3] );
Executes 'qesap.py ... terraform' and provides a robust retry mechanism for transient
cloud provider errors. The primary motivation is to avoid a slow and brittle
destroy-and-recreate cycle for sporadic issues, such as an Azure API timeout like
"InternalExecutionError: An internal execution error occurred. Please retry later.".
Upon detecting a recoverable error from the `error_list`, the function waits for a
randomized backoff period and then re-executes the 'terraform plan' and 'apply'
commands. This approach works because the 'plan' command implicitly refreshes the
state from the cloud, detecting any drift or partially completed operations. This
allows Terraform to intelligently correct the state on the next apply, rather than
starting from scratch.
The function returns its execution result in the same format as `qesap_execute`.
Search for a list of strings in the Ansible log file.
Returns 1 if any of the strings are found in the log file, 0 otherwise.
Return the path of the generated inventory
Get the number of cluster nodes from the inventory.yaml
Get the cluster nodes' names from the inventory.yaml
Return the path used by the qesap script as -chdir argument for terraform
It is useful if test would like to call terraform
Return the path where sap-linuxlab/community.sles-for-sap
has been installed
qesap_prepare_env(variables=>{dict with variables}, provider => 'aws');
Prepare terraform environment.
- creates file structures
- pulls git repository
- external configuration files
- installs pip requirements and OS packages
- generates configuration files with qesap script
For variables example see 'qesap_yaml_replace'
Returns only result, failure handling has to be done by calling method.
qesap_ansible_softfail(logfile => '/tmp/ansible.log.txt' )
Call record_soft_failure if a conventional message is detected in the ansible log
from qe-sap-deployment (check the README of it).
This function does not return anything.
Download the playbook from the test code repo
that is on the worker within the running JompHost.
Use Ansible to run a command remotely on some or all
the hosts from the inventory.yaml
Use Ansible to run a command remotely and get the stdout.
Command could be executed with elevated privileges
qesap_ansible_script_output_file(cmd => 'crm status', provider => 'aws', host => 'vmhana01', root => 1);
It uses playbook data/sles4sap/script_output.yaml
1. ansible-playbook runs the playbook
2. the playbook executes the command remotely and redirects the output to file, both remotely
3. qesap_ansible_fetch_file downloads the file locally
4. the file is read and stored to be returned to the caller
Return is the local full path of the file containing the output of the
remotely executed command.
Return the output of a command executed on the remote machine via Ansible.
Use Ansible to fetch a file from remote.
Command could be executed with elevated privileges
qesap_ansible_fetch_file(provider => 'aws', host => 'vmhana01', root => 1);
It uses playbook data/sles4sap/fetch_file.yaml
1. ansible-playbook run the playbook
3. the playbook download the file locally
4. the file is read and stored to be returned to the caller
Return the local path of the downloaded file.
Compose the ansible-playbook argument for the registration.yaml playbook,
about an additional module registration
-e sles_modules='[{"key":"SLES-LTSS-Extended-Security/12.5/x86_64","value":"*******"}]'
Known limitation is that registration.yaml supports multiple modules to be registered,
this code only supports one.
Return a list of the public IP addresses of the systems
deployed by qe-sap-deployment, as reported by C<terraform output>.
Needs to run after C<qesap_execute(cmd => 'terraform');> call.
Probe specified port on the remote host each 5sec till response.
Return -1 in case of timeout
Return total time of retry loop in case of pass.
Run crm report on a host and upload the resulting tarball to openqa
Generate supportconfig log on a host and upload the resulting tarball to openqa
List of commands to collect logs from a deployed cluster
Collect logs from a deployed cluster.
This is about logs generated remotely on the two HANA nodes,
`crm report` collection is part of this function.
Collect y2logs from nodes of a deployed cluster
Collect supportconfig logs from all HANA nodes of a deployed cluster
Compose the deployment name. It always has the JobId
Generic function to compose a aws cli command with:
- `aws ec2` something
- use both `filter` and `query`
- has text output
Adds a 'ip -> name' pair in the end of /etc/hosts in the hosts
Downloads assets required for re-using infrastructure from previously exported test.
qesap_import_instances(<$test_id>)
Downloads assets required for re-using infrastructure from previously exported test.
qesap_export_instances()
Delete leftover peering resources for AWS jobs that finished without cleaning up.
This only works for resources created by jobs that run on the same openqa server
that the current job is running on.
qesap_terraform_ansible_deploy_retry( error_log=>$error_log )
error_log - ansible error log file name
Retry to deploy terraform + ansible. This function is only expected to be called if a previous `qesap.py`
execution returns a non zero exit code. If this function is called after a successful execution,
the qesap_ansible_error_detection will not find anything wrong in the log, wrongly concluding that
an unknown error is in the log and skipping the retry and this function will return 1..
Return 0: this function manage the failure properly, perform a retry and retry was a successful deployment
Return 1: something went wrong or this function does not know what to do with the failure
qesap_ansible_error_detection( error_log=>$error_log )
Inspect the provided Ansible log and search for known issue in the log
Also provide a nice record_info to summarize the error
Return:
- 0: unable to detect errors
- 1: generic fatal error
- 2: reboot timeout
- 3: no sudo password