lorax/src/pylorax/api/yumbase.py
Brian C. Lane 8080abda67 Log and exit on metadata update errors at startup
A bad system repo can cause lorax-composer to fail to start. Instead of
a traceback log the error and exit.

(note that the exit still results in an OSError traceback due to part of
it running as root, this needs to be addressed in another commit).
2018-07-17 13:47:26 -07:00

130 lines
4.2 KiB
Python

#
# Copyright (C) 2017 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# pylint: disable=bad-preconf-access
import logging
log = logging.getLogger("lorax-composer")
import ConfigParser
from fnmatch import fnmatchcase
from glob import glob
import os
import yum
from yum.Errors import YumBaseError
# This is a hack to short circuit yum's internal logging
yum.logginglevels._added_handlers = True
from pylorax.sysutils import joinpaths
def get_base_object(conf):
"""Get the Yum object with settings from the config file
:param conf: configuration object
:type conf: ComposerParser
:returns: A Yum base object
:rtype: YumBase
"""
cachedir = os.path.abspath(conf.get("composer", "cache_dir"))
yumconf = os.path.abspath(conf.get("composer", "yum_conf"))
yumroot = os.path.abspath(conf.get("composer", "yum_root"))
repodir = os.path.abspath(conf.get("composer", "repo_dir"))
c = ConfigParser.ConfigParser()
# add the main section
section = "main"
data = {"cachedir": cachedir,
"keepcache": 0,
"gpgcheck": 0,
"plugins": 0,
"assumeyes": 1,
"reposdir": "",
"tsflags": "nodocs"}
if conf.get_default("yum", "proxy", None):
data["proxy"] = conf.get("yum", "proxy")
if conf.has_option("yum", "sslverify") and not conf.getboolean("yum", "sslverify"):
data["sslverify"] = "0"
c.add_section(section)
map(lambda (key, value): c.set(section, key, value), data.items())
# write the yum configuration file
with open(yumconf, "w") as f:
c.write(f)
# create the yum base object
yb = yum.YumBase()
yb.preconf.fn = yumconf
yb.preconf.root = yumroot
if not os.path.isdir(yb.preconf.root):
os.makedirs(yb.preconf.root)
_releasever = conf.get_default("composer", "releasever", None)
if not _releasever:
distroverpkg = ['system-release(releasever)', 'redhat-release']
# Use yum private function to guess the releasever
_releasever = yum.config._getsysver("/", distroverpkg)
log.info("releasever = %s", _releasever)
yb.preconf.releasever = _releasever
# Turn on as much yum logging as we can
yb.preconf.debuglevel = 6
yb.preconf.errorlevel = 6
yb.logger.setLevel(logging.DEBUG)
yb.verbose_logger.setLevel(logging.DEBUG)
# Gather up all the available repo files, add the ones matching "repos":"enabled" patterns
enabled_repos = conf.get("repos", "enabled").split(",")
repo_files = glob(joinpaths(repodir, "*.repo"))
if not conf.has_option("repos", "use_system_repos") or conf.getboolean("repos", "use_system_repos"):
repo_files.extend(glob("/etc/yum.repos.d/*.repo"))
for repo_file in repo_files:
name = os.path.basename(repo_file)[:-5]
if any(map(lambda pattern: fnmatchcase(name, pattern), enabled_repos)): # pylint: disable=cell-var-from-loop
yb.getReposFromConfigFile(repo_file)
# Update the metadata from the enabled repos to speed up later operations
log.info("Updating yum repository metadata")
update_metadata(yb)
return yb
def update_metadata(yb):
"""Update the metadata for all the enabled repos
:param yb: The Yum base object
:type yb: yum.YumBase
:returns: None
:rtype: None
"""
for r in yb.repos.sort():
r.metadata_expire = 0
r.mdpolicy = "group:all"
try:
yb.doRepoSetup()
yb.repos.doSetup()
yb.repos.populateSack(mdtype='all', cacheonly=0)
except YumBaseError as e:
log.error("Failed to update metadata: %s", str(e))
raise RuntimeError("Fetching metadata failed: %s" % str(e))