diff options
author | Valentin Krasontovitsch <valkra@ihelse.net> | 2017-08-08 15:53:44 +0200 |
---|---|---|
committer | Brian Coca <bcoca@users.noreply.github.com> | 2017-08-10 09:25:56 -0400 |
commit | cfff72e9db71b8d21c7d283f116e68b1052b47bf (patch) | |
tree | 7792081f9dc81cd73751a81b1842ee6d6c3603c1 /lib/ansible/modules/packaging | |
parent | 13d2eb65681c8b99288715b624ae23d68dc33a84 (diff) | |
download | ansible-cfff72e9db71b8d21c7d283f116e68b1052b47bf.tar.gz |
Use apt-get as fallback for apt upgrade
In answer to #2540, `aptitude` was introduced as tool of choice for running
upgrades in the apt module and installing new packages that arise as
dependencies during upgrades.
This recently lead to problems, as for example Ubuntu Xenial (16.04) ships
without aptitude (installed).
Studying the man pages of both apt-get and aptitude, it appears that we can
achieve the effects of `aptitude safe-upgrade` using
```
apt-get upgrade --with-new-pkgs --autoremove
```
while `aptitude full-upgrade` seems to be identical to `apt-get dist-upgrade`.
We use `apt-get` as described above as a fall-back in case that `aptitude`
cannot be found, issuing a warning when it does so.
Furthermore it introduces a flag `force_apt_get` which may be used to enforce
usage of apt-get (which does not issue a warning).
The integration tests are updated accordingly.
Cf. also the discussion in #27370.
Fixes #18987
Diffstat (limited to 'lib/ansible/modules/packaging')
-rw-r--r-- | lib/ansible/modules/packaging/os/apt.py | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/lib/ansible/modules/packaging/os/apt.py b/lib/ansible/modules/packaging/os/apt.py index 2e090660e6..05a3f8d8ff 100644 --- a/lib/ansible/modules/packaging/os/apt.py +++ b/lib/ansible/modules/packaging/os/apt.py @@ -89,6 +89,7 @@ options: - 'If full, performs an aptitude full-upgrade.' - 'If dist, performs an apt-get dist-upgrade.' - 'Note: This does not upgrade a specific package, use state=latest for that.' + - 'Note: Since 2.4, apt-get is used as a fall-back if aptitude is not present.' version_added: "1.1" required: false default: "no" @@ -126,14 +127,21 @@ options: required: false default: false version_added: "2.1" + force_apt_get: + description: + - Force usage of apt-get instead of aptitude + required: false + default: false + version_added: "2.4" requirements: - python-apt (python 2) - python3-apt (python 3) - - aptitude + - aptitude (before 2.4) author: "Matthew Williams (@mgwilliams)" notes: - - Three of the upgrade modes (C(full), C(safe) and its alias C(yes)) require C(aptitude), otherwise - C(apt-get) suffices. + - Three of the upgrade modes (C(full), C(safe) and its alias C(yes)) + required C(aptitude) up to 2.3, since 2.4 C(apt-get) is used as a + fall-back. ''' EXAMPLES = ''' @@ -711,6 +719,7 @@ def cleanup(m, purge=False, force=False, operation=None, def upgrade(m, mode="yes", force=False, default_release=None, + use_apt_get=False, dpkg_options=expand_dpkg_options(DPKG_OPTIONS)): if m.check_mode: check_arg = '--simulate' @@ -719,19 +728,23 @@ def upgrade(m, mode="yes", force=False, default_release=None, apt_cmd = None prompt_regex = None - if mode == "dist": + if mode == "dist" or (mode == "full" and use_apt_get): # apt-get dist-upgrade apt_cmd = APT_GET_CMD upgrade_command = "dist-upgrade" - elif mode == "full": + elif mode == "full" and not use_apt_get: # aptitude full-upgrade apt_cmd = APTITUDE_CMD upgrade_command = "full-upgrade" else: - # aptitude safe-upgrade # mode=yes # default - apt_cmd = APTITUDE_CMD - upgrade_command = "safe-upgrade" - prompt_regex = r"(^Do you want to ignore this warning and proceed anyway\?|^\*\*\*.*\[default=.*\])" + if use_apt_get: + apt_cmd = APT_GET_CMD + upgrade_command = "upgrade --with-new-pkgs --autoremove" + else: + # aptitude safe-upgrade # mode=yes # default + apt_cmd = APTITUDE_CMD + upgrade_command = "safe-upgrade" + prompt_regex = r"(^Do you want to ignore this warning and proceed anyway\?|^\*\*\*.*\[default=.*\])" if force: if apt_cmd == APT_GET_CMD: @@ -860,6 +873,7 @@ def main(): autoremove=dict(type='bool', default='no'), autoclean=dict(type='bool', default='no'), only_upgrade=dict(type='bool', default=False), + force_apt_get=dict(type='bool', default=False), allow_unauthenticated=dict(default='no', aliases=['allow-unauthenticated'], type='bool'), ), mutually_exclusive=[['package', 'upgrade', 'deb']], @@ -894,8 +908,11 @@ def main(): if p['upgrade'] == 'no': p['upgrade'] = None - if not APTITUDE_CMD and p.get('upgrade', None) in ['full', 'safe', 'yes']: - module.fail_json(msg="Could not find aptitude. Please ensure it is installed.") + use_apt_get = p['force_apt_get'] + + if not use_apt_get and not APTITUDE_CMD and p.get('upgrade', None) in ['full', 'safe', 'yes']: + module.warn("Could not find aptitude. Using apt-get instead") + use_apt_get = True updated_cache = False updated_cache_time = 0 @@ -956,7 +973,7 @@ def main(): force_yes = p['force'] if p['upgrade']: - upgrade(module, p['upgrade'], force_yes, p['default_release'], dpkg_options) + upgrade(module, p['upgrade'], force_yes, p['default_release'], use_apt_get, dpkg_options) if p['deb']: if p['state'] != 'present': @@ -976,7 +993,7 @@ def main(): if latest and all_installed: if packages: module.fail_json(msg='unable to install additional packages when ugrading all installed packages') - upgrade(module, 'yes', force_yes, p['default_release'], dpkg_options) + upgrade(module, 'yes', force_yes, p['default_release'], use_apt_get, dpkg_options) if packages: for package in packages: |