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.
This commit is contained in:
TSDominguez 2017-07-25 23:12:29 +08:00 committed by ansibot
parent 372956c16a
commit b9a2dc979f

View file

@ -59,8 +59,10 @@ options:
- C(present) will make sure the package is installed. - C(present) will make sure the package is installed.
C(latest) will make sure the latest version of 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(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 required: false
choices: [ present, latest, absent ] choices: [ present, latest, absent, dist-upgrade ]
default: "present" default: "present"
type: type:
description: description:
@ -108,6 +110,12 @@ options:
required: false required: false
default: "no" default: "no"
choices: [ "yes", "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 # informational: requirements for nodes
requirements: requirements:
@ -160,6 +168,12 @@ EXAMPLES = '''
state: latest state: latest
type: patch 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" # Refresh repositories and update package "openssl"
- zypper: - zypper:
name: openssl name: openssl
@ -299,7 +313,7 @@ def parse_zypper_xml(m, cmd, fail_not_found=True, packages=None):
def get_cmd(m, subcommand): def get_cmd(m, subcommand):
"puts together the basic zypper command arguments with those passed to the module" "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' is_refresh = subcommand == 'refresh'
cmd = ['/usr/bin/zypper', '--quiet', '--non-interactive', '--xmlout'] cmd = ['/usr/bin/zypper', '--quiet', '--non-interactive', '--xmlout']
@ -308,7 +322,7 @@ def get_cmd(m, subcommand):
cmd.append('--no-gpg-checks') cmd.append('--no-gpg-checks')
cmd.append(subcommand) 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']]) cmd.extend(['--type', m.params['type']])
if m.check_mode and subcommand != 'search': if m.check_mode and subcommand != 'search':
cmd.append('--dry-run') cmd.append('--dry-run')
@ -320,6 +334,10 @@ def get_cmd(m, subcommand):
cmd.append('--force') cmd.append('--force')
if m.params['oldpackage']: if m.params['oldpackage']:
cmd.append('--oldpackage') cmd.append('--oldpackage')
if m.params['extra_args']:
args_list = m.params['extra_args'].split(' ')
cmd.extend(args_list)
return cmd return cmd
@ -394,6 +412,8 @@ def package_update_all(m):
retvals = {'rc': 0, 'stdout': '', 'stderr': ''} retvals = {'rc': 0, 'stdout': '', 'stderr': ''}
if m.params['type'] == 'patch': if m.params['type'] == 'patch':
cmdname = 'patch' cmdname = 'patch'
elif m.params['state'] == 'dist-upgrade':
cmdname = 'dist-upgrade'
else: else:
cmdname = 'update' cmdname = 'update'
@ -446,13 +466,14 @@ def main():
module = AnsibleModule( module = AnsibleModule(
argument_spec = dict( argument_spec = dict(
name = dict(required=True, aliases=['pkg'], type='list'), 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']), type = dict(required=False, default='package', choices=['package', 'patch', 'pattern', 'product', 'srcpackage', 'application']),
disable_gpg_check = dict(required=False, default='no', type='bool'), disable_gpg_check = dict(required=False, default='no', type='bool'),
disable_recommends = dict(required=False, default='yes', type='bool'), disable_recommends = dict(required=False, default='yes', type='bool'),
force = dict(required=False, default='no', type='bool'), force = dict(required=False, default='no', type='bool'),
update_cache = dict(required=False, aliases=['refresh'], default='no', type='bool'), update_cache = dict(required=False, aliases=['refresh'], default='no', type='bool'),
oldpackage = dict(required=False, default='no', type='bool'), oldpackage = dict(required=False, default='no', type='bool'),
extra_args = dict(required=False, default=None),
), ),
supports_check_mode = True supports_check_mode = True
) )
@ -472,8 +493,10 @@ def main():
module.fail_json(msg="Zypper refresh run failed.", **retvals) module.fail_json(msg="Zypper refresh run failed.", **retvals)
# Perform requested action # Perform requested action
if name == ['*'] and state == 'latest': if name == ['*'] and state in ['latest', 'dist-upgrade']:
packages_changed, retvals = package_update_all(module) packages_changed, retvals = package_update_all(module)
elif name != ['*'] and state == 'dist-upgrade':
module.fail_json(msg="Can not dist-upgrade specific packages.")
else: else:
if state in ['absent', 'removed']: if state in ['absent', 'removed']:
packages_changed, retvals = package_absent(module, name) packages_changed, retvals = package_absent(module, name)