diff --git a/lib/ansible/modules/packaging/os/dnf.py b/lib/ansible/modules/packaging/os/dnf.py index 4aa94f3beb7..6c32bad56c0 100644 --- a/lib/ansible/modules/packaging/os/dnf.py +++ b/lib/ansible/modules/packaging/os/dnf.py @@ -70,6 +70,14 @@ options: version_added: "2.3" default: "/" + releasever: + description: + - Specifies an alternative release from which all packages will be + installed. + required: false + version_added: "2.6" + default: null + autoremove: description: - If C(yes), removes all "leaf" packages from the system that were originally @@ -180,7 +188,7 @@ def _ensure_dnf(module): "Please install `{0}` package.".format(package)) -def _configure_base(module, base, conf_file, disable_gpg_check, installroot='/'): +def _configure_base(module, base, conf_file, disable_gpg_check, installroot='/', releasever=None): """Configure the dnf Base object.""" conf = base.conf @@ -196,6 +204,10 @@ def _configure_base(module, base, conf_file, disable_gpg_check, installroot='/') # Set installroot conf.installroot = installroot + # Set releasever + if releasever is not None: + conf.substitutions['releasever'] = releasever + # Change the configuration file path if provided if conf_file: # Fail if we can't read the configuration file. @@ -225,10 +237,10 @@ def _specify_repositories(base, disablerepo, enablerepo): repo.enable() -def _base(module, conf_file, disable_gpg_check, disablerepo, enablerepo, installroot): +def _base(module, conf_file, disable_gpg_check, disablerepo, enablerepo, installroot, releasever): """Return a fully configured dnf Base object.""" base = dnf.Base() - _configure_base(module, base, conf_file, disable_gpg_check, installroot) + _configure_base(module, base, conf_file, disable_gpg_check, installroot, releasever) _specify_repositories(base, disablerepo, enablerepo) base.fill_sack(load_system_repo='auto') return base @@ -477,6 +489,7 @@ def main(): disable_gpg_check=dict(default=False, type='bool'), installroot=dict(default='/', type='path'), autoremove=dict(type='bool'), + releasever=dict(default=None), ), required_one_of=[['name', 'list', 'autoremove']], mutually_exclusive=[['name', 'list'], ['autoremove', 'list']], @@ -501,7 +514,8 @@ def main(): if params['list']: base = _base( module, params['conf_file'], params['disable_gpg_check'], - params['disablerepo'], params['enablerepo'], params['installroot']) + params['disablerepo'], params['enablerepo'], params['installroot'], + params['releasever']) list_items(module, base, params['list']) else: # Note: base takes a long time to run so we want to check for failure @@ -510,7 +524,8 @@ def main(): module.fail_json(msg="This command has to be run under the root user.") base = _base( module, params['conf_file'], params['disable_gpg_check'], - params['disablerepo'], params['enablerepo'], params['installroot']) + params['disablerepo'], params['enablerepo'], params['installroot'], + params['releasever']) ensure(module, base, params['state'], params['name'], params['autoremove']) diff --git a/test/integration/targets/dnf/tasks/dnfreleasever.yml b/test/integration/targets/dnf/tasks/dnfreleasever.yml new file mode 100644 index 00000000000..ea4d9c5b5ac --- /dev/null +++ b/test/integration/targets/dnf/tasks/dnfreleasever.yml @@ -0,0 +1,48 @@ +# make an installroot +- name: Create installroot + local_action: + module: command mktemp -d "{{lookup('env', 'TMPDIR') | default('/tmp', true)}}/ansible.test.XXXXXX" + register: dnfroot + +- name: Make a necessary directory + file: + path: "/{{dnfroot.stdout}}/etc/dnf/vars" + state: directory + mode: 0755 + +- name: Populate directory + copy: + content: "{{ansible_distribution_version}}\n" + dest: "/{{dnfroot.stdout}}/etc/dnf/vars/releasever" + +- name: attempt releasever to the installroot + dnf: + name: filesystem + installroot: '/{{dnfroot.stdout}}' + releasever: 22 + register: dnf_result + +- name: check filesystem version + shell: rpm -q filesystem --root="/{{dnfroot.stdout}}/" + failed_when: False + register: rpm_result + +- debug: var=dnf_result +- debug: var=rpm_result + +- name: verify installation was done + assert: + that: + - "not dnf_result.failed | default(False)" + - "dnf_result.changed" + - "rpm_result.rc == 0" + +- name: verify the version + assert: + that: + - "rpm_result.stdout.find('fc22') != -1" + +- name: cleanup installroot + file: + path: "/{{dnfroot.stdout}}/" + state: absent diff --git a/test/integration/targets/dnf/tasks/main.yml b/test/integration/targets/dnf/tasks/main.yml index cd33b2f4621..f4931df3138 100644 --- a/test/integration/targets/dnf/tasks/main.yml +++ b/test/integration/targets/dnf/tasks/main.yml @@ -33,3 +33,8 @@ when: - ansible_distribution == 'Fedora' - ansible_distribution_major_version|int >= 23 + +- include: 'dnfreleasever.yml' + when: + - ansible_distribution == 'Fedora' + - ansible_distribution_major_version|int >= 23