1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

Fix installation of environment groups

In dnf, environment groups are separate from groups.  Need to handle
them separately when calling the API.

Fixes #2178

After upstream review, hande dnf-2.0 mandatory packages in groups

If mandatory packages in a group are not installed, a group will report
failure.  Fix this by catching the error and reporting after trying
to install the other packages and groups in the transaction.
This commit is contained in:
Toshio Kuratomi 2016-10-29 19:08:37 -07:00 committed by Matt Clay
parent 8414b466d7
commit 82d2a4810e

View file

@ -212,7 +212,7 @@ def _base(module, conf_file, disable_gpg_check, disablerepo, enablerepo):
base = dnf.Base() base = dnf.Base()
_configure_base(module, base, conf_file, disable_gpg_check) _configure_base(module, base, conf_file, disable_gpg_check)
_specify_repositories(base, disablerepo, enablerepo) _specify_repositories(base, disablerepo, enablerepo)
base.fill_sack() base.fill_sack(load_system_repo='auto')
return base return base
@ -289,6 +289,9 @@ def _install_remote_rpms(base, filenames):
def ensure(module, base, state, names): 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 allow_erasing = False
if names == ['*'] and state == 'latest': if names == ['*'] and state == 'latest':
base.upgrade_all() base.upgrade_all()
@ -297,34 +300,70 @@ def ensure(module, base, state, names):
if group_specs: if group_specs:
base.read_comps() base.read_comps()
pkg_specs = [p.strip() for p in pkg_specs]
filenames = [f.strip() for f in filenames]
groups = [] groups = []
environments = []
for group_spec in group_specs: for group_spec in group_specs:
group = base.comps.group_by_pattern(group_spec) group = base.comps.group_by_pattern(group_spec)
if group: if group:
groups.append(group) groups.append(group.strip())
else: else:
module.fail_json( environment = base.comps.environments_by_pattern(group_spec)
msg="No group {} available.".format(group_spec)) if environment:
environments.extend((e.id.strip() for e in environment))
else:
module.fail_json(
msg="No group {} available.".format(group_spec))
if state in ['installed', 'present']: if state in ['installed', 'present']:
# Install files. # Install files.
_install_remote_rpms(base, (f.strip() for f in filenames)) _install_remote_rpms(base, filenames)
# Install groups. # Install groups.
for group in (g.strip() for g in groups): for group in groups:
base.group_install(group, dnf.const.GROUP_PACKAGE_TYPES) try:
base.group_install(group, dnf.const.GROUP_PACKAGE_TYPES)
except dnf.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, dnf.const.GROUP_PACKAGE_TYPES)
except dnf.exceptions.Error as e:
failures.append((group, e))
# Install packages. # 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) _mark_package_install(module, base, pkg_spec)
elif state == 'latest': elif state == 'latest':
# "latest" is same as "installed" for filenames. # "latest" is same as "installed" for filenames.
_install_remote_rpms(base, filenames) _install_remote_rpms(base, filenames)
for group in groups: for group in groups:
try: try:
base.group_upgrade(group) try:
except dnf.exceptions.CompsError: base.group_upgrade(group)
# If not already installed, try to install. except dnf.exceptions.CompsError:
base.group_install(group, dnf.const.GROUP_PACKAGE_TYPES) # If not already installed, try to install.
base.group_install(group, dnf.const.GROUP_PACKAGE_TYPES)
except dnf.exceptions.Error as e:
failures.append((group, e))
for environment in environments:
try:
try:
base.environment_upgrade(environment)
except dnf.exceptions.CompsError:
# If not already installed, try to install.
base.environment_install(group, dnf.const.GROUP_PACKAGE_TYPES)
except dnf.exceptions.Error as e:
failures.append((group, e))
for pkg_spec in pkg_specs: for pkg_spec in pkg_specs:
# best effort causes to install the latest package # best effort causes to install the latest package
# even if not previously installed # even if not previously installed
@ -341,18 +380,27 @@ def ensure(module, base, state, names):
for group in groups: for group in groups:
if installed.filter(name=group.name): if installed.filter(name=group.name):
base.group_remove(group) base.group_remove(group)
for pkg_spec in pkg_specs: for pkg_spec in pkg_specs:
if installed.filter(name=pkg_spec): if installed.filter(name=pkg_spec):
base.remove(pkg_spec) base.remove(pkg_spec)
# Like the dnf CLI we want to allow recursive removal of dependent # Like the dnf CLI we want to allow recursive removal of dependent
# packages # packages
allow_erasing = True allow_erasing = True
if not base.resolve(allow_erasing=allow_erasing): 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") module.exit_json(msg="Nothing to do")
else: else:
if module.check_mode: 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) module.exit_json(changed=True)
base.download_packages(base.transaction.install_set) base.download_packages(base.transaction.install_set)
base.do_transaction() base.do_transaction()
response = {'changed': True, 'results': []} response = {'changed': True, 'results': []}
@ -361,6 +409,9 @@ def ensure(module, base, state, names):
for package in base.transaction.remove_set: for package in base.transaction.remove_set:
response['results'].append("Removed: {0}".format(package)) 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) module.exit_json(**response)