diff --git a/changelogs/fragments/24004-yum-dnf-add-download_dir-param.yml b/changelogs/fragments/24004-yum-dnf-add-download_dir-param.yml new file mode 100644 index 0000000000..b846c190dc --- /dev/null +++ b/changelogs/fragments/24004-yum-dnf-add-download_dir-param.yml @@ -0,0 +1,2 @@ +minor_changes: + - yum/dnf - Add download_dir param (https://github.com/ansible/ansible/issues/24004) diff --git a/lib/ansible/module_utils/yumdnf.py b/lib/ansible/module_utils/yumdnf.py index 3aaa335ae5..ca6c73e11f 100644 --- a/lib/ansible/module_utils/yumdnf.py +++ b/lib/ansible/module_utils/yumdnf.py @@ -29,6 +29,7 @@ yumdnf_argument_spec = dict( disable_plugin=dict(type='list', default=[]), disablerepo=dict(type='list', default=[]), download_only=dict(type='bool', default=False), + download_dir=dict(type='str', default=None), enable_plugin=dict(type='list', default=[]), enablerepo=dict(type='list', default=[]), exclude=dict(type='list', default=[]), @@ -73,6 +74,7 @@ class YumDnf(with_metaclass(ABCMeta, object)): self.disable_plugin = self.module.params['disable_plugin'] self.disablerepo = self.module.params.get('disablerepo', []) self.download_only = self.module.params['download_only'] + self.download_dir = self.module.params['download_dir'] self.enable_plugin = self.module.params['enable_plugin'] self.enablerepo = self.module.params.get('enablerepo', []) self.exclude = self.module.params['exclude'] diff --git a/lib/ansible/modules/packaging/os/dnf.py b/lib/ansible/modules/packaging/os/dnf.py index b08d34ff8c..44c14fbba8 100644 --- a/lib/ansible/modules/packaging/os/dnf.py +++ b/lib/ansible/modules/packaging/os/dnf.py @@ -190,6 +190,12 @@ options: type: bool default: "yes" version_added: "2.8" + download_dir: + description: + - Specifies an alternate directory to store packages. + - Has an effect only if I(download_only) is specified. + type: str + version_added: "2.8" 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 @@ -564,6 +570,8 @@ class DnfModule(YumDnf): if self.download_only: conf.downloadonly = True + if self.download_dir: + conf.destdir = self.download_dir # Default in dnf upstream is true conf.clean_requirements_on_remove = self.autoremove @@ -1122,6 +1130,10 @@ class DnfModule(YumDnf): self.module.exit_json(**response) try: + if self.download_only and self.download_dir and self.base.conf.destdir: + dnf.util.ensure_dir(self.base.conf.destdir) + self.base.repos.all().pkgdir = self.base.conf.destdir + self.base.download_packages(self.base.transaction.install_set) except dnf.exceptions.DownloadError as e: self.module.fail_json( @@ -1171,6 +1183,14 @@ class DnfModule(YumDnf): results=[], ) + # Check if download_dir is called correctly + if self.download_dir: + if LooseVersion(dnf.__version__) < LooseVersion('2.6.2'): + self.module.fail_json( + msg="download_dir requires dnf>=2.6.2. Current dnf version is %s" % dnf.__version__, + results=[], + ) + if self.update_cache and not self.names and not self.list: self.base = self._base( self.conf_file, self.disable_gpg_check, self.disablerepo, diff --git a/lib/ansible/modules/packaging/os/yum.py b/lib/ansible/modules/packaging/os/yum.py index b74e7dd221..52d33f275e 100644 --- a/lib/ansible/modules/packaging/os/yum.py +++ b/lib/ansible/modules/packaging/os/yum.py @@ -197,6 +197,12 @@ options: type: bool default: "yes" version_added: "2.8" + download_dir: + description: + - Specifies an alternate directory to store packages. + - Has an effect only if I(download_only) is specified. + type: str + version_added: "2.8" 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. @@ -1385,6 +1391,9 @@ class YumModule(YumDnf): if self.download_only: self.yum_basecmd.extend(['--downloadonly']) + if self.download_dir: + self.yum_basecmd.extend(['--downloaddir=%s' % self.download_dir]) + if self.installroot != '/': # do not setup installroot by default, because of error # CRITICAL:yum.cli:Config Error: Error accessing file for config file:////etc/yum.conf diff --git a/test/integration/targets/dnf/tasks/dnf.yml b/test/integration/targets/dnf/tasks/dnf.yml index 75d1429db2..7adc2870b8 100644 --- a/test/integration/targets/dnf/tasks/dnf.yml +++ b/test/integration/targets/dnf/tasks/dnf.yml @@ -233,13 +233,12 @@ dnf: name=sos installroot='/' register: dnf_result -# Test download_only - name: uninstall sos for downloadonly test dnf: name: sos state: absent -- name: install sos +- name: Test download_only dnf: name: sos state: latest @@ -264,6 +263,33 @@ - "dnf_result is success" - "not dnf_result is changed" +- name: uninstall sos for downloadonly/downloaddir test + dnf: + name: sos + state: absent + +- name: Test download_only/download_dir + dnf: + name: sos + state: latest + download_only: true + download_dir: "/var/tmp/packages" + register: dnf_result + +- name: verify dnf output + assert: + that: + - "dnf_result is success" + - "dnf_result is changed" + +- command: "ls /var/tmp/packages" + register: ls_out + +- name: Verify specified download_dir was used + assert: + that: + - "'sos' in ls_out.stdout" + # GROUP INSTALL - name: install Custom Group group dnf: diff --git a/test/integration/targets/yum/tasks/yum.yml b/test/integration/targets/yum/tasks/yum.yml index 7957e8bb16..29da992560 100644 --- a/test/integration/targets/yum/tasks/yum.yml +++ b/test/integration/targets/yum/tasks/yum.yml @@ -303,8 +303,7 @@ state: removed register: yum_result -# Test download_only -- name: install sos +- name: Test download_only yum: name: sos state: latest @@ -329,6 +328,33 @@ - "yum_result is success" - "not yum_result is changed" +- name: uninstall sos for downloadonly/downloaddir test + yum: + name: sos + state: absent + +- name: Test download_only/download_dir + yum: + name: sos + state: latest + download_only: true + download_dir: "/var/tmp/packages" + register: yum_result + +- name: verify yum output + assert: + that: + - "yum_result is success" + - "yum_result is changed" + +- command: "ls /var/tmp/packages" + register: ls_out + +- name: Verify specified download_dir was used + assert: + that: + - "'sos' in ls_out.stdout" + - name: install group yum: name: "@Development Tools"