File: //lib/python3.6/site-packages/dnf-plugins/releasever-adapter.py
#!/usr/bin/env python3
#
# Version:1.0
#
# To install this plugin, just drop it into
# /usr/lib/python3.6/site-packages/dnf-plugins, and
# make sure you have 'plugins=1' in your /etc/yum.conf.
# You also need to create the following configuration
# file, if not installed through an RPM:
#
# /etc/yum/pluginconf.d/releasever_adaptation.conf:
# [main]
# enabled=1
# [releasevermapping]
# release_dict={'2.1903' : '7', '3' : '8'}
# [reposlist]
# include=docker-ce.repo, epel.repo
#
import re
import dnf
import ast
import logging
from dnf.yum import misc
from urllib.parse import urlparse, urlunparse
include = None
release_dict = None
done_repos = set()
class ReleaseverAdaptation(dnf.Plugin):
"""DNF Plugin to parse baseurl in repositories"""
name = 'releasever-adapter'
def __init__(self, base, cli):
super().__init__(base, cli)
self.base = base
def config(self):
conf = self.read_config(self.base.conf)
include = conf.get('reposlist', 'include')
release_dict = conf.get('releasevermapping', 'release_dict')
release_dict = ast.literal_eval(release_dict)
repos_list = include.replace(' ', '').split(',')
releasever = self.get_releasever()
mattching_repos = self.parse_repos(repos_list)
repomirrors = {}
for repo in mattching_repos:
if repo.id in done_repos:
continue
if str(repo) in repomirrors:
continue
type = "baseurl" if repo.baseurl else "metalink" if \
repo.metalink else "mirrorlist"
repo_urls = parse_baseurl({"baseurl": repo.baseurl,
"metalink": [repo.metalink],
"mirrorlist": [repo.mirrorlist]}[type],
releasever, release_dict)
setattr(repo, type, repo_urls if repo.baseurl else repo_urls[0])
repo.failovermethod = 'priority'
done_repos.add(repo.id)
def parse_repos(self, repos_list):
mattching_repos = []
for repo_name in repos_list:
repo_key = repo_name.split('.')[0] + '*'
matching = self.base.repos.get_matching(repo_key)
for repo in matching:
if repo.enabled:
mattching_repos.append(repo)
return mattching_repos
def get_releasever(self):
return self.base.conf.substitutions['releasever']
def parse_baseurl(urllist, releasever, dict):
"""
This function replaces the releasever variables in baseurl.
@param urllist : list of baseurl or metalink or mirrorlist of a repository.
@type urllist : list
@releasever: the os releasever
@type releasever: str
@param dict : Mapping of releasever variables.
@type dict : dict
@rtype : list
@return : The list of adaptaed baseurl or metalink or mirrorlist.
"""
pattern = re.compile(r'[\/\-\=]' + releasever + r'[\/\&]')
goodurls = []
skipped = None
for url in urllist:
if url in ['', None]:
continue
try:
(s, b, p, q, f, o) = urlparse(url)
except (ValueError, IndexError, KeyError) as e:
s = 'blah'
if s not in ['http', 'ftp', 'file', 'https']:
skipped = url
continue
url = urlunparse((s, b, p, q, f, o))
release_var_group = re.search(pattern, url)
try:
release_var = release_var_group.group()
release_version = dict[releasever]
except (KeyError, AttributeError):
goodurls.append(url)
else:
new_release_var = release_var.replace(releasever, dict[releasever])
adapted_url = url.replace(release_var, new_release_var)
goodurls.append(adapted_url)
if skipped is not None:
if goodurls:
logger.warning('DnfRepo Warning: Some mirror URLs are not\
using ftp, http[s] or file.\n Eg. %s' % misc.to_utf8(skipped))
else:
logger.error('DnfRepo Error: All mirror URLs are not using\
ftp, http[s] or file.\n Eg. %s' % misc.to_utf8(skipped))
return goodurls