diff -uNr vanilla/lib/ansible/modules/extras/packaging/os/dnf.py ansible-2.2.0.0/lib/ansible/modules/extras/packaging/os/dnf.py
--- vanilla/lib/ansible/modules/extras/packaging/os/dnf.py 2016-10-31 20:43:38.000000000 -0700
+++ ansible-2.2.0.0/lib/ansible/modules/extras/packaging/os/dnf.py 2016-11-04 10:27:21.501410357 -0700
@@ -179,7 +179,7 @@
base = dnf.Base()
_configure_base(module, base, conf_file, disable_gpg_check)
_specify_repositories(base, disablerepo, enablerepo)
- base.fill_sack()
+ base.fill_sack(load_system_repo='auto')
return base
@@ -256,6 +256,9 @@
def ensure(module, base, state, names):
+ # Accumulate failures. Package management modules install what they can
+ # and fail with a message about what they can't.
+ failures = []
allow_erasing = False
if names == ['*'] and state == 'latest':
base.upgrade_all()
@@ -264,34 +267,70 @@
if group_specs:
base.read_comps()
+ pkg_specs = [p.strip() for p in pkg_specs]
+ filenames = [f.strip() for f in filenames]
groups = []
- for group_spec in group_specs:
+ environments = []
+ for group_spec in (g.strip() for g in group_specs):
group = base.comps.group_by_pattern(group_spec)
if group:
groups.append(group)
else:
- module.fail_json(
- msg="No group {} available.".format(group_spec))
+ environment = base.comps.environment_by_pattern(group_spec)
+ if environment:
+ environments.append(environment.id)
+ else:
+ module.fail_json(
+ msg="No group {} available.".format(group_spec))
if state in ['installed', 'present']:
# Install files.
- _install_remote_rpms(base, (f.strip() for f in filenames))
+ _install_remote_rpms(base, filenames)
+
# Install groups.
- for group in (g.strip() for g in groups):
- base.group_install(group, const.GROUP_PACKAGE_TYPES)
+ for group in groups:
+ try:
+ base.group_install(group, const.GROUP_PACKAGE_TYPES)
+ except exceptions.Error as e:
+ # In dnf 2.0 if all the mandatory packages in a group do
+ # not install, an error is raised. We want to capture
+ # this but still install as much as possible.
+ failures.append((group, e))
+
+ for environment in environments:
+ try:
+ base.environment_install(environment, const.GROUP_PACKAGE_TYPES)
+ except exceptions.Error as e:
+ failures.append((group, e))
+
# Install packages.
- for pkg_spec in (p.strip() for p in pkg_specs):
+ for pkg_spec in pkg_specs:
_mark_package_install(module, base, pkg_spec)
elif state == 'latest':
# "latest" is same as "installed" for filenames.
_install_remote_rpms(base, filenames)
+
for group in groups:
try:
- base.group_upgrade(group)
- except exceptions.CompsError:
- # If not already installed, try to install.
- base.group_install(group, const.GROUP_PACKAGE_TYPES)
+ try:
+ base.group_upgrade(group)
+ except exceptions.CompsError:
+ # If not already installed, try to install.
+ base.group_install(group, const.GROUP_PACKAGE_TYPES)
+ except exceptions.Error as e:
+ failures.append((group, e))
+
+ for environment in environments:
+ try:
+ try:
+ base.environment_upgrade(environment)
+ except exceptions.CompsError:
+ # If not already installed, try to install.
+ base.environment_install(group, const.GROUP_PACKAGE_TYPES)
+ except exceptions.Error as e:
+ failures.append((group, e))
+
for pkg_spec in pkg_specs:
# best effort causes to install the latest package
# even if not previously installed
@@ -304,22 +343,41 @@
module.fail_json(
msg="Cannot remove paths -- please specify package name.")
- installed = base.sack.query().installed()
for group in groups:
- if installed.filter(name=group.name):
+ try:
base.group_remove(group)
+ except dnf.exceptions.CompsError:
+ # Group is already uninstalled.
+ pass
+
+ for envioronment in environments:
+ try:
+ base.environment_remove(environment)
+ except dnf.exceptions.CompsError:
+ # Environment is already uninstalled.
+ pass
+
+ installed = base.sack.query().installed()
for pkg_spec in pkg_specs:
if installed.filter(name=pkg_spec):
base.remove(pkg_spec)
+
# Like the dnf CLI we want to allow recursive removal of dependent
# packages
allow_erasing = True
if not base.resolve(allow_erasing=allow_erasing):
+ if failures:
+ module.fail_json(msg='Failed to install some of the specified packages',
+ failures=failures)
module.exit_json(msg="Nothing to do")
else:
if module.check_mode:
+ if failures:
+ module.fail_json(msg='Failed to install some of the specified packages',
+ failures=failures)
module.exit_json(changed=True)
+
base.download_packages(base.transaction.install_set)
base.do_transaction()
response = {'changed': True, 'results': []}
@@ -328,6 +386,9 @@
for package in base.transaction.remove_set:
response['results'].append("Removed: {0}".format(package))
+ if failures:
+ module.fail_json(msg='Failed to install some of the specified packages',
+ failures=failures)
module.exit_json(**response)