diff --git a/changelogs/fragments/73820-yumdnf-add_cacheonly_option.yaml b/changelogs/fragments/73820-yumdnf-add_cacheonly_option.yaml new file mode 100644 index 00000000000..84ebb7bc6ab --- /dev/null +++ b/changelogs/fragments/73820-yumdnf-add_cacheonly_option.yaml @@ -0,0 +1,4 @@ +--- +minor_changes: + - yum - Add ``cacheonly`` option (https://github.com/ansible/ansible/issues/69397). + - dnf - Add ``cacheonly`` option (https://github.com/ansible/ansible/issues/69397). diff --git a/lib/ansible/module_utils/yumdnf.py b/lib/ansible/module_utils/yumdnf.py index 6407670980f..58827312bf4 100644 --- a/lib/ansible/module_utils/yumdnf.py +++ b/lib/ansible/module_utils/yumdnf.py @@ -26,6 +26,7 @@ yumdnf_argument_spec = dict( allow_downgrade=dict(type='bool', default=False), autoremove=dict(type='bool', default=False), bugfix=dict(required=False, type='bool', default=False), + cacheonly=dict(type='bool', default=False), conf_file=dict(type='str'), disable_excludes=dict(type='str', default=None), disable_gpg_check=dict(type='bool', default=False), @@ -71,6 +72,7 @@ class YumDnf(with_metaclass(ABCMeta, object)): self.allow_downgrade = self.module.params['allow_downgrade'] self.autoremove = self.module.params['autoremove'] self.bugfix = self.module.params['bugfix'] + self.cacheonly = self.module.params['cacheonly'] self.conf_file = self.module.params['conf_file'] self.disable_excludes = self.module.params['disable_excludes'] self.disable_gpg_check = self.module.params['disable_gpg_check'] diff --git a/lib/ansible/modules/dnf.py b/lib/ansible/modules/dnf.py index b3a73fc1a4e..e1851a13573 100644 --- a/lib/ansible/modules/dnf.py +++ b/lib/ansible/modules/dnf.py @@ -228,6 +228,12 @@ options: type: bool default: "no" version_added: "2.11" + cacheonly: + description: + - Tells dnf to run entirely from system cache; does not download or update metadata. + type: bool + default: "no" + version_added: "2.12" notes: - When used with a `loop:` each package will be processed individually, it is much more efficient to pass the list directly to the `name` option. - Group removal doesn't work if the group was installed with Ansible because @@ -609,6 +615,9 @@ class DnfModule(YumDnf): if self.download_dir: conf.destdir = self.download_dir + if self.cacheonly: + conf.cacheonly = True + # Default in dnf upstream is true conf.clean_requirements_on_remove = self.autoremove diff --git a/lib/ansible/modules/yum.py b/lib/ansible/modules/yum.py index 7c5c2759021..0c1d1728777 100644 --- a/lib/ansible/modules/yum.py +++ b/lib/ansible/modules/yum.py @@ -236,6 +236,12 @@ options: version_added: "1.5" default: "yes" type: bool + cacheonly: + description: + - Tells yum to run entirely from system cache; does not download or update metadata. + default: "no" + type: bool + version_added: "2.12" notes: - When used with a `loop:` each package will be processed individually, it is much more efficient to pass the list directly to the `name` option. @@ -1558,6 +1564,9 @@ class YumModule(YumDnf): if self.disable_excludes: self.yum_basecmd.extend(['--disableexcludes=%s' % self.disable_excludes]) + if self.cacheonly: + self.yum_basecmd.extend(['--cacheonly']) + if self.download_only: self.yum_basecmd.extend(['--downloadonly']) diff --git a/test/integration/targets/dnf/tasks/cacheonly.yml b/test/integration/targets/dnf/tasks/cacheonly.yml new file mode 100644 index 00000000000..a5c84a37040 --- /dev/null +++ b/test/integration/targets/dnf/tasks/cacheonly.yml @@ -0,0 +1,15 @@ +--- +- name: Test cacheonly (clean before testing) + command: dnf clean all + +- name: Try installing from cache where it has been cleaned + dnf: + name: sos + state: latest + cacheonly: true + register: dnf_result + +- name: Verify dnf has not changed + assert: + that: + - "not dnf_result is changed" diff --git a/test/integration/targets/dnf/tasks/main.yml b/test/integration/targets/dnf/tasks/main.yml index 51ab7d20023..429d24fd0e6 100644 --- a/test/integration/targets/dnf/tasks/main.yml +++ b/test/integration/targets/dnf/tasks/main.yml @@ -66,3 +66,7 @@ - include_tasks: nobest.yml when: (ansible_distribution == 'Fedora' and ansible_distribution_major_version is version('24', '>=')) or (ansible_distribution in ['RedHat', 'CentOS'] and ansible_distribution_major_version is version('8', '>=')) + +- include_tasks: cacheonly.yml + when: (ansible_distribution == 'Fedora' and ansible_distribution_major_version is version('23', '>=')) or + (ansible_distribution in ['RedHat', 'CentOS'] and ansible_distribution_major_version is version('8', '>=')) diff --git a/test/integration/targets/yum/tasks/cacheonly.yml b/test/integration/targets/yum/tasks/cacheonly.yml new file mode 100644 index 00000000000..03cbd0e9c6c --- /dev/null +++ b/test/integration/targets/yum/tasks/cacheonly.yml @@ -0,0 +1,16 @@ +--- +- name: Test cacheonly (clean before testing) + command: yum clean all + +- name: Try installing from cache where it has been cleaned + yum: + name: sos + state: latest + cacheonly: true + register: yum_result + ignore_errors: true + +- name: Verify yum failure + assert: + that: + - "yum_result is failed" diff --git a/test/integration/targets/yum/tasks/main.yml b/test/integration/targets/yum/tasks/main.yml index 6ea63fa9c6c..157124a99cf 100644 --- a/test/integration/targets/yum/tasks/main.yml +++ b/test/integration/targets/yum/tasks/main.yml @@ -76,3 +76,7 @@ - ansible_architecture == 'x86_64' # Our output parsing expects us to be on yum, not dnf - ansible_distribution_major_version is version('7', '<=') + +- import_tasks: cacheonly.yml + when: + - ansible_distribution in ['RedHat', 'CentOS', 'ScientificLinux', 'Fedora']