From b9a2dc979fe1630ce219c4d66258bf99f3eaef94 Mon Sep 17 00:00:00 2001 From: TSDominguez Date: Tue, 25 Jul 2017 23:12:29 +0800 Subject: [PATCH] Add dist-upgrade and extra_args to zypper module (#21313) * Implement state='dist-upgrade' Implements `zypper dist-upgrade` for the zypper module. This follows how `zypper upgrade` is invoked, except `state='dist-upgrade'`. Setting name to anything other than '*' would cause the module to error out. `dist-upgrade` affects all packages and would not make sense to apply to a specific package. * Implement option extra_args Add option to append additional arguments to zypper command. This should be able to accommodate other options that are not (yet) covered by zypper module. Arguments are given as if written in the command line, complete with dashes. --- lib/ansible/modules/packaging/os/zypper.py | 33 ++++++++++++++++++---- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/lib/ansible/modules/packaging/os/zypper.py b/lib/ansible/modules/packaging/os/zypper.py index 1194c42fb57..7787665536e 100644 --- a/lib/ansible/modules/packaging/os/zypper.py +++ b/lib/ansible/modules/packaging/os/zypper.py @@ -59,8 +59,10 @@ options: - C(present) will make sure the package is installed. C(latest) will make sure the latest version of the package is installed. C(absent) will make sure the specified package is not installed. + C(dist-upgrade) will make sure the latest version of all installed packages from all enabled repositories is installed. + - When using C(dist-upgrade), I(name) should be C('*'). required: false - choices: [ present, latest, absent ] + choices: [ present, latest, absent, dist-upgrade ] default: "present" type: description: @@ -108,6 +110,12 @@ options: required: false default: "no" choices: [ "yes", "no" ] + extra_args: + version_added: "2.4" + required: false + description: + - Add additional options to C(zypper) command. + - Options should be supplied in a single line as if given in the command line. # informational: requirements for nodes requirements: @@ -160,6 +168,12 @@ EXAMPLES = ''' state: latest type: patch +# Perform a dist-upgrade with additional arguments +- zypper: + name: '*' + state: dist-upgrade + extra_args: '--no-allow-vendor-change --allow-arch-change' + # Refresh repositories and update package "openssl" - zypper: name: openssl @@ -299,7 +313,7 @@ def parse_zypper_xml(m, cmd, fail_not_found=True, packages=None): def get_cmd(m, subcommand): "puts together the basic zypper command arguments with those passed to the module" - is_install = subcommand in ['install', 'update', 'patch'] + is_install = subcommand in ['install', 'update', 'patch', 'dist-upgrade'] is_refresh = subcommand == 'refresh' cmd = ['/usr/bin/zypper', '--quiet', '--non-interactive', '--xmlout'] @@ -308,7 +322,7 @@ def get_cmd(m, subcommand): cmd.append('--no-gpg-checks') cmd.append(subcommand) - if subcommand != 'patch' and not is_refresh: + if subcommand not in ['patch', 'dist-upgrade'] and not is_refresh: cmd.extend(['--type', m.params['type']]) if m.check_mode and subcommand != 'search': cmd.append('--dry-run') @@ -320,6 +334,10 @@ def get_cmd(m, subcommand): cmd.append('--force') if m.params['oldpackage']: cmd.append('--oldpackage') + if m.params['extra_args']: + args_list = m.params['extra_args'].split(' ') + cmd.extend(args_list) + return cmd @@ -394,6 +412,8 @@ def package_update_all(m): retvals = {'rc': 0, 'stdout': '', 'stderr': ''} if m.params['type'] == 'patch': cmdname = 'patch' + elif m.params['state'] == 'dist-upgrade': + cmdname = 'dist-upgrade' else: cmdname = 'update' @@ -446,13 +466,14 @@ def main(): module = AnsibleModule( argument_spec = dict( name = dict(required=True, aliases=['pkg'], type='list'), - state = dict(required=False, default='present', choices=['absent', 'installed', 'latest', 'present', 'removed']), + state = dict(required=False, default='present', choices=['absent', 'installed', 'latest', 'present', 'removed', 'dist-upgrade']), type = dict(required=False, default='package', choices=['package', 'patch', 'pattern', 'product', 'srcpackage', 'application']), disable_gpg_check = dict(required=False, default='no', type='bool'), disable_recommends = dict(required=False, default='yes', type='bool'), force = dict(required=False, default='no', type='bool'), update_cache = dict(required=False, aliases=['refresh'], default='no', type='bool'), oldpackage = dict(required=False, default='no', type='bool'), + extra_args = dict(required=False, default=None), ), supports_check_mode = True ) @@ -472,8 +493,10 @@ def main(): module.fail_json(msg="Zypper refresh run failed.", **retvals) # Perform requested action - if name == ['*'] and state == 'latest': + if name == ['*'] and state in ['latest', 'dist-upgrade']: packages_changed, retvals = package_update_all(module) + elif name != ['*'] and state == 'dist-upgrade': + module.fail_json(msg="Can not dist-upgrade specific packages.") else: if state in ['absent', 'removed']: packages_changed, retvals = package_absent(module, name)