|
|
@ -254,6 +254,21 @@ EXAMPLES = '''
|
|
|
|
name: httpd
|
|
|
|
name: httpd
|
|
|
|
state: absent
|
|
|
|
state: absent
|
|
|
|
autoremove: no
|
|
|
|
autoremove: no
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- name: install a modularity appstream with defined stream and profile
|
|
|
|
|
|
|
|
dnf:
|
|
|
|
|
|
|
|
name: @postgresql:9.6/client
|
|
|
|
|
|
|
|
state: present
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- name: install a modularity appstream with defined stream
|
|
|
|
|
|
|
|
dnf:
|
|
|
|
|
|
|
|
name: @postgresql:9.6
|
|
|
|
|
|
|
|
state: present
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- name: install a modularity appstream with defined profile
|
|
|
|
|
|
|
|
dnf:
|
|
|
|
|
|
|
|
name: @postgresql/client
|
|
|
|
|
|
|
|
state: present
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
import os
|
|
|
|
import os
|
|
|
@ -296,6 +311,11 @@ class DnfModule(YumDnf):
|
|
|
|
self.lockfile = "/var/cache/dnf/*_lock.pid"
|
|
|
|
self.lockfile = "/var/cache/dnf/*_lock.pid"
|
|
|
|
self.pkg_mgr_name = "dnf"
|
|
|
|
self.pkg_mgr_name = "dnf"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
self.with_modules = dnf.base.WITH_MODULES
|
|
|
|
|
|
|
|
except AttributeError:
|
|
|
|
|
|
|
|
self.with_modules = False
|
|
|
|
|
|
|
|
|
|
|
|
def _sanitize_dnf_error_msg(self, spec, error):
|
|
|
|
def _sanitize_dnf_error_msg(self, spec, error):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
For unhandled dnf.exceptions.Error scenarios, there are certain error
|
|
|
|
For unhandled dnf.exceptions.Error scenarios, there are certain error
|
|
|
@ -592,6 +612,7 @@ class DnfModule(YumDnf):
|
|
|
|
results=[],
|
|
|
|
results=[],
|
|
|
|
rc=1
|
|
|
|
rc=1
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
return base
|
|
|
|
return base
|
|
|
|
|
|
|
|
|
|
|
|
def list_items(self, command):
|
|
|
|
def list_items(self, command):
|
|
|
@ -720,17 +741,35 @@ class DnfModule(YumDnf):
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
def _parse_spec_group_file(self):
|
|
|
|
def _parse_spec_group_file(self):
|
|
|
|
pkg_specs, grp_specs, filenames = [], [], []
|
|
|
|
pkg_specs, grp_specs, env_specs, module_specs, filenames = [], [], [], [], []
|
|
|
|
|
|
|
|
already_loaded_comps = False # Only load this if necessary, it's slow
|
|
|
|
|
|
|
|
|
|
|
|
for name in self.names:
|
|
|
|
for name in self.names:
|
|
|
|
if name.endswith(".rpm"):
|
|
|
|
if name.endswith(".rpm"):
|
|
|
|
if '://' in name:
|
|
|
|
if '://' in name:
|
|
|
|
name = self.fetch_rpm_from_url(name)
|
|
|
|
name = self.fetch_rpm_from_url(name)
|
|
|
|
filenames.append(name)
|
|
|
|
filenames.append(name)
|
|
|
|
elif name.startswith("@"):
|
|
|
|
elif name.startswith("@") or ('/' in name):
|
|
|
|
grp_specs.append(name[1:])
|
|
|
|
if not already_loaded_comps:
|
|
|
|
|
|
|
|
self.base.read_comps()
|
|
|
|
|
|
|
|
already_loaded_comps = True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
grp_env_mdl_candidate = name[1:].strip()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
grp = self.base.comps.group_by_pattern(grp_env_mdl_candidate)
|
|
|
|
|
|
|
|
if grp:
|
|
|
|
|
|
|
|
grp_specs.append(grp.id)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
env = self.base.comps.environment_by_pattern(grp_env_mdl_candidate)
|
|
|
|
|
|
|
|
if env:
|
|
|
|
|
|
|
|
env_specs.append(env.id)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mdl = self.module_base._get_modules(grp_env_mdl_candidate)
|
|
|
|
|
|
|
|
if mdl[0]:
|
|
|
|
|
|
|
|
module_specs.append(grp_env_mdl_candidate)
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
pkg_specs.append(name)
|
|
|
|
pkg_specs.append(name)
|
|
|
|
return pkg_specs, grp_specs, filenames
|
|
|
|
return pkg_specs, grp_specs, env_specs, module_specs, filenames
|
|
|
|
|
|
|
|
|
|
|
|
def _update_only(self, pkgs):
|
|
|
|
def _update_only(self, pkgs):
|
|
|
|
not_installed = []
|
|
|
|
not_installed = []
|
|
|
@ -784,6 +823,16 @@ class DnfModule(YumDnf):
|
|
|
|
rc=1,
|
|
|
|
rc=1,
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _is_module_installed(self, module_spec):
|
|
|
|
|
|
|
|
if self.with_modules:
|
|
|
|
|
|
|
|
module_spec = module_spec.strip()
|
|
|
|
|
|
|
|
module_list, nsv = self.module_base._get_modules(module_spec)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if nsv.stream in self.base._moduleContainer.getEnabledStream(nsv.name):
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return False # seems like a sane default
|
|
|
|
|
|
|
|
|
|
|
|
def ensure(self):
|
|
|
|
def ensure(self):
|
|
|
|
allow_erasing = False
|
|
|
|
allow_erasing = False
|
|
|
|
|
|
|
|
|
|
|
@ -816,27 +865,10 @@ class DnfModule(YumDnf):
|
|
|
|
failure_response['msg'] = "Depsolve Error occured attempting to upgrade all packages"
|
|
|
|
failure_response['msg'] = "Depsolve Error occured attempting to upgrade all packages"
|
|
|
|
self.module.fail_json(**failure_response)
|
|
|
|
self.module.fail_json(**failure_response)
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
pkg_specs, group_specs, filenames = self._parse_spec_group_file()
|
|
|
|
pkg_specs, group_specs, env_specs, module_specs, filenames = self._parse_spec_group_file()
|
|
|
|
if group_specs:
|
|
|
|
|
|
|
|
self.base.read_comps()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pkg_specs = [p.strip() for p in pkg_specs]
|
|
|
|
pkg_specs = [p.strip() for p in pkg_specs]
|
|
|
|
filenames = [f.strip() for f in filenames]
|
|
|
|
filenames = [f.strip() for f in filenames]
|
|
|
|
groups = []
|
|
|
|
|
|
|
|
environments = []
|
|
|
|
|
|
|
|
for group_spec in (g.strip() for g in group_specs):
|
|
|
|
|
|
|
|
group = self.base.comps.group_by_pattern(group_spec)
|
|
|
|
|
|
|
|
if group:
|
|
|
|
|
|
|
|
groups.append(group.id)
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
environment = self.base.comps.environment_by_pattern(group_spec)
|
|
|
|
|
|
|
|
if environment:
|
|
|
|
|
|
|
|
environments.append(environment.id)
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
self.module.fail_json(
|
|
|
|
|
|
|
|
msg="No group {0} available.".format(group_spec),
|
|
|
|
|
|
|
|
results=[],
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if self.state in ['installed', 'present']:
|
|
|
|
if self.state in ['installed', 'present']:
|
|
|
|
# Install files.
|
|
|
|
# Install files.
|
|
|
@ -844,8 +876,25 @@ class DnfModule(YumDnf):
|
|
|
|
for filename in filenames:
|
|
|
|
for filename in filenames:
|
|
|
|
response['results'].append("Installed {0}".format(filename))
|
|
|
|
response['results'].append("Installed {0}".format(filename))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Install modules
|
|
|
|
|
|
|
|
if module_specs and self.with_modules:
|
|
|
|
|
|
|
|
for module in module_specs:
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
if not self._is_module_installed(module):
|
|
|
|
|
|
|
|
response['results'].append("Module {0} installed.".format(module))
|
|
|
|
|
|
|
|
self.module_base.install([module])
|
|
|
|
|
|
|
|
except dnf.exceptions.MarkingErrors as e:
|
|
|
|
|
|
|
|
failure_response['failures'].append(
|
|
|
|
|
|
|
|
" ".join(
|
|
|
|
|
|
|
|
(
|
|
|
|
|
|
|
|
' '.join(module),
|
|
|
|
|
|
|
|
to_native(e)
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# Install groups.
|
|
|
|
# Install groups.
|
|
|
|
for group in groups:
|
|
|
|
for group in group_specs:
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
group_pkg_count_installed = self.base.group_install(group, dnf.const.GROUP_PACKAGE_TYPES)
|
|
|
|
group_pkg_count_installed = self.base.group_install(group, dnf.const.GROUP_PACKAGE_TYPES)
|
|
|
|
if group_pkg_count_installed == 0:
|
|
|
|
if group_pkg_count_installed == 0:
|
|
|
@ -861,7 +910,7 @@ class DnfModule(YumDnf):
|
|
|
|
# this but still install as much as possible.
|
|
|
|
# this but still install as much as possible.
|
|
|
|
failure_response['failures'].append(" ".join((group, to_native(e))))
|
|
|
|
failure_response['failures'].append(" ".join((group, to_native(e))))
|
|
|
|
|
|
|
|
|
|
|
|
for environment in environments:
|
|
|
|
for environment in env_specs:
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
self.base.environment_install(environment, dnf.const.GROUP_PACKAGE_TYPES)
|
|
|
|
self.base.environment_install(environment, dnf.const.GROUP_PACKAGE_TYPES)
|
|
|
|
except dnf.exceptions.DepsolveError as e:
|
|
|
|
except dnf.exceptions.DepsolveError as e:
|
|
|
@ -870,6 +919,13 @@ class DnfModule(YumDnf):
|
|
|
|
except dnf.exceptions.Error as e:
|
|
|
|
except dnf.exceptions.Error as e:
|
|
|
|
failure_response['failures'].append(" ".join((environment, to_native(e))))
|
|
|
|
failure_response['failures'].append(" ".join((environment, to_native(e))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if module_specs and not self.with_modules:
|
|
|
|
|
|
|
|
# This means that the group or env wasn't found in comps
|
|
|
|
|
|
|
|
self.module.fail_json(
|
|
|
|
|
|
|
|
msg="No group {0} available.".format(module_specs[0]),
|
|
|
|
|
|
|
|
results=[],
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
# Install packages.
|
|
|
|
# Install packages.
|
|
|
|
if self.update_only:
|
|
|
|
if self.update_only:
|
|
|
|
not_installed = self._update_only(pkg_specs)
|
|
|
|
not_installed = self._update_only(pkg_specs)
|
|
|
@ -890,7 +946,24 @@ class DnfModule(YumDnf):
|
|
|
|
for filename in filenames:
|
|
|
|
for filename in filenames:
|
|
|
|
response['results'].append("Installed {0}".format(filename))
|
|
|
|
response['results'].append("Installed {0}".format(filename))
|
|
|
|
|
|
|
|
|
|
|
|
for group in groups:
|
|
|
|
# Upgrade modules
|
|
|
|
|
|
|
|
if module_specs and self.with_modules:
|
|
|
|
|
|
|
|
for module in module_specs:
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
if self._is_module_installed(module):
|
|
|
|
|
|
|
|
response['results'].append("Module {0} upgraded.".format(module))
|
|
|
|
|
|
|
|
self.module_base.upgrade([module])
|
|
|
|
|
|
|
|
except dnf.exceptions.MarkingErrors as e:
|
|
|
|
|
|
|
|
failure_response['failures'].append(
|
|
|
|
|
|
|
|
" ".join(
|
|
|
|
|
|
|
|
(
|
|
|
|
|
|
|
|
' '.join(module),
|
|
|
|
|
|
|
|
to_native(e)
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for group in group_specs:
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
self.base.group_upgrade(group)
|
|
|
|
self.base.group_upgrade(group)
|
|
|
@ -906,7 +979,7 @@ class DnfModule(YumDnf):
|
|
|
|
except dnf.exceptions.Error as e:
|
|
|
|
except dnf.exceptions.Error as e:
|
|
|
|
failure_response['failures'].append(" ".join((group, to_native(e))))
|
|
|
|
failure_response['failures'].append(" ".join((group, to_native(e))))
|
|
|
|
|
|
|
|
|
|
|
|
for environment in environments:
|
|
|
|
for environment in env_specs:
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
self.base.environment_upgrade(environment)
|
|
|
|
self.base.environment_upgrade(environment)
|
|
|
@ -942,7 +1015,25 @@ class DnfModule(YumDnf):
|
|
|
|
results=[],
|
|
|
|
results=[],
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
for group in groups:
|
|
|
|
# Remove modules
|
|
|
|
|
|
|
|
if module_specs and self.with_modules:
|
|
|
|
|
|
|
|
for module in module_specs:
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
if self._is_module_installed(module):
|
|
|
|
|
|
|
|
response['results'].append("Module {0} removed.".format(module))
|
|
|
|
|
|
|
|
self.module_base.disable([module])
|
|
|
|
|
|
|
|
self.module_base.remove([module])
|
|
|
|
|
|
|
|
except dnf.exceptions.MarkingErrors as e:
|
|
|
|
|
|
|
|
failure_response['failures'].append(
|
|
|
|
|
|
|
|
" ".join(
|
|
|
|
|
|
|
|
(
|
|
|
|
|
|
|
|
' '.join(module),
|
|
|
|
|
|
|
|
to_native(e)
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for group in group_specs:
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
self.base.group_remove(group)
|
|
|
|
self.base.group_remove(group)
|
|
|
|
except dnf.exceptions.CompsError:
|
|
|
|
except dnf.exceptions.CompsError:
|
|
|
@ -957,7 +1048,7 @@ class DnfModule(YumDnf):
|
|
|
|
# https://bugzilla.redhat.com/show_bug.cgi?id=1620324
|
|
|
|
# https://bugzilla.redhat.com/show_bug.cgi?id=1620324
|
|
|
|
pass
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
for environment in environments:
|
|
|
|
for environment in env_specs:
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
self.base.environment_remove(environment)
|
|
|
|
self.base.environment_remove(environment)
|
|
|
|
except dnf.exceptions.CompsError:
|
|
|
|
except dnf.exceptions.CompsError:
|
|
|
@ -1080,6 +1171,9 @@ class DnfModule(YumDnf):
|
|
|
|
self.enablerepo, self.installroot
|
|
|
|
self.enablerepo, self.installroot
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if self.with_modules:
|
|
|
|
|
|
|
|
self.module_base = dnf.module.module_base.ModuleBase(self.base)
|
|
|
|
|
|
|
|
|
|
|
|
self.ensure()
|
|
|
|
self.ensure()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|