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:
parent
8414b466d7
commit
82d2a4810e
1 changed files with 63 additions and 12 deletions
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue