forked from msvsphere/leapp-repository
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
3.4 KiB
94 lines
3.4 KiB
import os
|
|
import warnings
|
|
|
|
from leapp.libraries.common.config.version import get_source_major_version
|
|
|
|
try:
|
|
import dnf
|
|
except ImportError:
|
|
dnf = None
|
|
warnings.warn('Could not import the `dnf` python module.', ImportWarning)
|
|
|
|
try:
|
|
import hawkey
|
|
except ImportError:
|
|
hawkey = None
|
|
warnings.warn('Could not import the `hawkey` python module.', ImportWarning)
|
|
|
|
|
|
def _create_or_get_dnf_base(base=None):
|
|
if not base:
|
|
# The DNF command reads /etc/yum/vars/releasever, but the DNF library does not. It parses redhat-release
|
|
# package to retrieve system's major version which it then uses as $releasever. However, some systems might
|
|
# have repositories only for the exact system version (including the minor number). In a case when
|
|
# /etc/yum/vars/releasever is present, read its contents so that we can access repositores on such systems.
|
|
conf = dnf.conf.Conf()
|
|
pkg_manager = 'yum' if get_source_major_version() == '7' else 'dnf'
|
|
releasever_path = '/etc/{0}/vars/releasever'.format(pkg_manager)
|
|
if os.path.exists(releasever_path):
|
|
with open(releasever_path) as releasever_file:
|
|
releasever = releasever_file.read().strip()
|
|
conf.substitutions['releasever'] = releasever
|
|
else:
|
|
conf.substitutions['releasever'] = get_source_major_version()
|
|
|
|
base = dnf.Base(conf=conf)
|
|
base.init_plugins()
|
|
base.read_all_repos()
|
|
# configure plugins after the repositories are loaded
|
|
# e.g. the amazon-id plugin requires loaded repositories
|
|
# for the proper configuration.
|
|
base.configure_plugins()
|
|
base.fill_sack()
|
|
return base
|
|
|
|
|
|
def get_modules(base=None):
|
|
"""
|
|
Return info about all module streams as a list of libdnf.module.ModulePackage objects.
|
|
"""
|
|
if not dnf:
|
|
return []
|
|
base = _create_or_get_dnf_base(base)
|
|
|
|
module_base = dnf.module.module_base.ModuleBase(base)
|
|
# this method is absent on RHEL 7, in which case there are no modules anyway
|
|
if not hasattr(module_base, 'get_modules'):
|
|
return []
|
|
return module_base.get_modules('*')[0]
|
|
|
|
|
|
def get_enabled_modules():
|
|
"""
|
|
Return currently enabled module streams as a list of libdnf.module.ModulePackage objects.
|
|
"""
|
|
if not dnf:
|
|
return []
|
|
|
|
base = _create_or_get_dnf_base()
|
|
modules = get_modules(base)
|
|
|
|
# if modules are not supported (RHEL 7), base.sack._moduleContainer won't exist
|
|
# luckily in that case modules are empty and the element won't even be accessed
|
|
return [m for m in modules if base.sack._moduleContainer.isEnabled(m)]
|
|
|
|
|
|
def map_installed_rpms_to_modules():
|
|
"""
|
|
Map installed modular packages to the module streams they come from.
|
|
"""
|
|
modules = get_modules()
|
|
# empty on RHEL 7 because of no modules
|
|
if not modules:
|
|
return {}
|
|
# create a reverse mapping from the RPMS to module streams
|
|
# key: tuple of 4 strings representing a NVRA (name, version, release, arch) of an RPM
|
|
# value: tuple of 2 strings representing a module and its stream
|
|
rpm_streams = {}
|
|
for module in modules:
|
|
for rpm in module.getArtifacts():
|
|
nevra = hawkey.split_nevra(rpm)
|
|
rpm_key = (nevra.name, nevra.version, nevra.release, nevra.arch)
|
|
rpm_streams[rpm_key] = (module.getName(), module.getStream())
|
|
return rpm_streams
|