mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-05-02 15:21:25 -07:00
Add zypper skip post errors feature (#9973)
* Add zypper skip post errors feature * Add feature to handle zypper return code 107 with skip_post_errors (default: false). * Add integration test to verify the skip_post_errors flag. * Add changelog fragment Issue: #9972 Issue-Ref: https://github.com/ansible-collections/community.general/issues/9972 Co-authored-by: Felix Fontein <felix@fontein.de> * Update plugins/modules/zypper.py * Update changelogs/fragments/9972-zypper-skip-post-errors.yml Co-authored-by: Felix Fontein <felix@fontein.de> * Update tests/integration/targets/zypper/tasks/zypper.yml Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com> --------- Co-authored-by: Felix Fontein <felix@fontein.de> Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
This commit is contained in:
parent
1243846c3a
commit
80252b29f8
5 changed files with 127 additions and 3 deletions
2
changelogs/fragments/9972-zypper-skip-post-errors.yml
Normal file
2
changelogs/fragments/9972-zypper-skip-post-errors.yml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
minor_changes:
|
||||||
|
- zypper - adds ``skip_post_errors`` that allows to skip RPM post-install errors (Zypper return code 107) (https://github.com/ansible-collections/community.general/issues/9972).
|
|
@ -158,6 +158,13 @@ options:
|
||||||
description:
|
description:
|
||||||
- Adds C(--quiet) option to I(zypper) install/update command.
|
- Adds C(--quiet) option to I(zypper) install/update command.
|
||||||
version_added: '10.2.0'
|
version_added: '10.2.0'
|
||||||
|
skip_post_errors:
|
||||||
|
type: bool
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
description:
|
||||||
|
- When set to V(true), ignore I(zypper) return code 107 (post install script errors).
|
||||||
|
version_added: '10.6.0'
|
||||||
notes:
|
notes:
|
||||||
- When used with a C(loop:) each package is processed individually, it is much more efficient to pass the list directly
|
- When used with a C(loop:) each package is processed individually, it is much more efficient to pass the list directly
|
||||||
to the O(name) option.
|
to the O(name) option.
|
||||||
|
@ -248,6 +255,12 @@ EXAMPLES = r"""
|
||||||
state: present
|
state: present
|
||||||
environment:
|
environment:
|
||||||
ZYPP_LOCK_TIMEOUT: 20
|
ZYPP_LOCK_TIMEOUT: 20
|
||||||
|
|
||||||
|
- name: Install the package with post-install error without failing
|
||||||
|
community.general.zypper:
|
||||||
|
name: <package_with_post_install_error>
|
||||||
|
state: present
|
||||||
|
skip_post_errors: true
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
@ -344,12 +357,13 @@ def parse_zypper_xml(m, cmd, fail_not_found=True, packages=None):
|
||||||
m.fail_json(msg=errmsg, rc=rc, stdout=stdout, stderr=stderr, cmd=cmd)
|
m.fail_json(msg=errmsg, rc=rc, stdout=stdout, stderr=stderr, cmd=cmd)
|
||||||
else:
|
else:
|
||||||
return {}, rc, stdout, stderr
|
return {}, rc, stdout, stderr
|
||||||
elif rc in [0, 102, 103, 106]:
|
elif rc in [0, 102, 103, 106, 107]:
|
||||||
# zypper exit codes
|
# zypper exit codes
|
||||||
# 0: success
|
# 0: success
|
||||||
# 106: signature verification failed
|
# 106: signature verification failed
|
||||||
# 102: ZYPPER_EXIT_INF_REBOOT_NEEDED - Returned after a successful installation of a patch which requires reboot of computer.
|
# 102: ZYPPER_EXIT_INF_REBOOT_NEEDED - Returned after a successful installation of a patch which requires reboot of computer.
|
||||||
# 103: zypper was upgraded, run same command again
|
# 103: zypper was upgraded, run same command again
|
||||||
|
# 107: ZYPPER_EXIT_INF_RPM_SCRIPT_FAILED - Some of the packages %post install scripts returned an error, but package is installed.
|
||||||
if packages is None:
|
if packages is None:
|
||||||
firstrun = True
|
firstrun = True
|
||||||
packages = {}
|
packages = {}
|
||||||
|
@ -368,14 +382,18 @@ def parse_zypper_xml(m, cmd, fail_not_found=True, packages=None):
|
||||||
# if this was the first run and it failed with 103
|
# if this was the first run and it failed with 103
|
||||||
# run zypper again with the same command to complete update
|
# run zypper again with the same command to complete update
|
||||||
return parse_zypper_xml(m, cmd, fail_not_found=fail_not_found, packages=packages)
|
return parse_zypper_xml(m, cmd, fail_not_found=fail_not_found, packages=packages)
|
||||||
|
if rc == 107 and m.params['skip_post_errors'] and firstrun:
|
||||||
|
# if this was the first run and it failed with 107 with skip_post_errors flag
|
||||||
|
# run zypper again with the same command to complete update
|
||||||
|
return parse_zypper_xml(m, cmd, fail_not_found=fail_not_found, packages=packages)
|
||||||
|
|
||||||
# apply simple_errors logic to rc 0,102,103,106
|
# apply simple_errors logic to rc 0,102,103,106,107
|
||||||
if m.params['simple_errors']:
|
if m.params['simple_errors']:
|
||||||
stdout = get_simple_errors(dom) or stdout
|
stdout = get_simple_errors(dom) or stdout
|
||||||
|
|
||||||
return packages, rc, stdout, stderr
|
return packages, rc, stdout, stderr
|
||||||
|
|
||||||
# apply simple_errors logic to rc other than 0,102,103,106
|
# apply simple_errors logic to rc other than 0,102,103,106,107
|
||||||
if m.params['simple_errors']:
|
if m.params['simple_errors']:
|
||||||
stdout = get_simple_errors(dom) or stdout
|
stdout = get_simple_errors(dom) or stdout
|
||||||
|
|
||||||
|
@ -602,6 +620,7 @@ def main():
|
||||||
clean_deps=dict(required=False, default=False, type='bool'),
|
clean_deps=dict(required=False, default=False, type='bool'),
|
||||||
simple_errors=dict(required=False, default=False, type='bool'),
|
simple_errors=dict(required=False, default=False, type='bool'),
|
||||||
quiet=dict(required=False, default=True, type='bool'),
|
quiet=dict(required=False, default=True, type='bool'),
|
||||||
|
skip_post_errors=dict(required=False, default=False, type='bool'),
|
||||||
),
|
),
|
||||||
supports_check_mode=True
|
supports_check_mode=True
|
||||||
)
|
)
|
||||||
|
|
15
tests/integration/targets/zypper/files/post_error.spec
Normal file
15
tests/integration/targets/zypper/files/post_error.spec
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
Summary: Post error RPM
|
||||||
|
Name: post_error
|
||||||
|
Version: 1
|
||||||
|
Release: 0
|
||||||
|
License: GPLv3
|
||||||
|
Group: Applications/System
|
||||||
|
BuildArch: noarch
|
||||||
|
|
||||||
|
%description
|
||||||
|
Post error RPM
|
||||||
|
|
||||||
|
%files
|
||||||
|
|
||||||
|
%post
|
||||||
|
exit 1
|
|
@ -0,0 +1,3 @@
|
||||||
|
GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
SPDX-FileCopyrightText: Ansible Project
|
|
@ -255,6 +255,91 @@
|
||||||
that:
|
that:
|
||||||
- "stat_result.stat.exists == true"
|
- "stat_result.stat.exists == true"
|
||||||
|
|
||||||
|
# Build and install an empty rpm with error in post script
|
||||||
|
- name: uninstall post_error
|
||||||
|
zypper:
|
||||||
|
name: post_error
|
||||||
|
state: removed
|
||||||
|
|
||||||
|
- name: install rpmbuild
|
||||||
|
zypper:
|
||||||
|
name: rpmbuild
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: clean zypper RPM cache
|
||||||
|
file:
|
||||||
|
name: /var/cache/zypper/RPMS
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: create directory
|
||||||
|
file:
|
||||||
|
path: "{{ remote_tmp_dir | expanduser }}/zypper2"
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: copy spec file
|
||||||
|
copy:
|
||||||
|
src: post_error.spec
|
||||||
|
dest: "{{ remote_tmp_dir | expanduser }}/zypper2/post_error.spec"
|
||||||
|
|
||||||
|
- name: build rpm
|
||||||
|
command: |
|
||||||
|
rpmbuild -bb \
|
||||||
|
--define "_topdir {{remote_tmp_dir | expanduser }}/zypper2/rpm-build"
|
||||||
|
--define "_builddir %{_topdir}" \
|
||||||
|
--define "_rpmdir %{_topdir}" \
|
||||||
|
--define "_srcrpmdir %{_topdir}" \
|
||||||
|
--define "_specdir {{remote_tmp_dir | expanduser}}/zypper2" \
|
||||||
|
--define "_sourcedir %{_topdir}" \
|
||||||
|
{{ remote_tmp_dir }}/zypper2/post_error.spec
|
||||||
|
register: rpm_build_result
|
||||||
|
|
||||||
|
- name: install post_error rpm with skip_post_errors
|
||||||
|
zypper:
|
||||||
|
name: "{{ remote_tmp_dir | expanduser }}/zypper2/rpm-build/noarch/post_error-1-0.noarch.rpm"
|
||||||
|
disable_gpg_check: true
|
||||||
|
skip_post_errors: true
|
||||||
|
register: zypper_result
|
||||||
|
|
||||||
|
- name: check post_error rpm
|
||||||
|
shell: rpm -q post_error
|
||||||
|
failed_when: false
|
||||||
|
register: rpm_result
|
||||||
|
|
||||||
|
- name: verify installation of post_error
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "zypper_result.rc == 0"
|
||||||
|
- "zypper_result.changed"
|
||||||
|
- "rpm_result.rc == 0"
|
||||||
|
|
||||||
|
- name: uninstall post_error
|
||||||
|
zypper:
|
||||||
|
name: post_error
|
||||||
|
state: removed
|
||||||
|
|
||||||
|
- name: install post_error rpm without skip_post_errors
|
||||||
|
zypper:
|
||||||
|
name: "{{ remote_tmp_dir | expanduser }}/zypper2/rpm-build/noarch/post_error-1-0.noarch.rpm"
|
||||||
|
disable_gpg_check: true
|
||||||
|
register: zypper_result
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: check post_error rpm
|
||||||
|
shell: rpm -q post_error
|
||||||
|
failed_when: false
|
||||||
|
register: rpm_result
|
||||||
|
|
||||||
|
- name: verify installation of post_error
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "zypper_result.rc == 107"
|
||||||
|
- "not zypper_result.changed"
|
||||||
|
- "rpm_result.rc == 0"
|
||||||
|
|
||||||
|
- name: uninstall post_error
|
||||||
|
zypper:
|
||||||
|
name: post_error
|
||||||
|
state: removed
|
||||||
|
|
||||||
# test simultaneous remove and install using +- prefixes
|
# test simultaneous remove and install using +- prefixes
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue