[yum-cvs] yum/yum __init__.py, 1.138, 1.139 config.py, 1.77, 1.78 parser.py, 1.3, 1.4 plugins.py, 1.17, 1.18 repos.py, 1.83, 1.84
Menno Smits
mjs at login.linux.duke.edu
Tue Oct 25 12:28:46 UTC 2005
Update of /home/groups/yum/cvs/yum/yum
In directory login:/tmp/cvs-serv17120/yum
Modified Files:
__init__.py config.py parser.py plugins.py repos.py
Log Message:
Major overhaul of configuration file handling.
Index: __init__.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum/__init__.py,v
retrieving revision 1.138
retrieving revision 1.139
diff -u -r1.138 -r1.139
--- __init__.py 18 Oct 2005 05:27:07 -0000 1.138
+++ __init__.py 25 Oct 2005 12:28:44 -0000 1.139
@@ -34,6 +34,7 @@
import rpmUtils.arch
import newcomps
import config
+import parser
import repos
import misc
import transactioninfo
@@ -79,55 +80,51 @@
def doConfigSetup(self, fn='/etc/yum.conf', root='/'):
"""basic stub function for doing configuration setup"""
- self.conf = config.yumconf(configfile=fn, root=root)
+ self.conf = config.readMainConfig(fn, root)
+ self.yumvar = self.conf.yumvar
self.getReposFromConfig()
def getReposFromConfig(self):
"""read in repositories from config main and .repo files"""
-
+
reposlist = []
- # look through our repositories.
- for section in self.conf.cfg.sections(): # loop through the list of sections
- if section != 'main': # must be a repoid
- try:
- thisrepo = config.cfgParserRepo(section, self.conf, self.conf.cfg)
- except (Errors.RepoError, Errors.ConfigError), e:
- self.errorlog(2, e)
- continue
- else:
- reposlist.append(thisrepo)
- # reads through each reposdir for *.repo
- # does not read recursively
- # read each of them in using confpp, then parse them same as any other repo
- # section - as above.
+ # Check yum.conf for repositories
+ for section in self.conf.cfg.sections():
+ # All sections except [main] are repositories
+ if section == 'main':
+ continue
+
+ try:
+ thisrepo = config.readRepoConfig(self.conf.cfg, section, self.conf)
+ except (Errors.RepoError, Errors.ConfigError), e:
+ self.errorlog(2, e)
+ else:
+ reposlist.append(thisrepo)
+
+ # Read .repo files from directories specified by the reposdir option
+ # (typically /etc/yum.repos.d and /etc/yum/repos.d)
+ parser = config.IncludedDirConfigParser(vars=self.yumvar)
for reposdir in self.conf.reposdir:
- if os.path.exists(self.conf.installroot + '/' + reposdir):
+ if os.path.exists(self.conf.installroot+'/'+reposdir):
reposdir = self.conf.installroot + '/' + reposdir
-
+
if os.path.isdir(reposdir):
- repofn = glob.glob(reposdir+'/*.repo')
- repofn.sort()
-
- for fn in repofn:
- if not os.path.isfile(fn):
- continue
- try:
- cfg, sections = config.parseDotRepo(fn)
- except Errors.ConfigError, e:
- self.errorlog(2, e)
- continue
+ #XXX: why can't we just pass the list of files?
+ files = ' '.join(glob.glob('%s/*.repo' % reposdir))
+ #XXX: error catching here
+ parser.read(files)
- for section in sections:
- try:
- thisrepo = config.cfgParserRepo(section, self.conf,
- cfg)
- reposlist.append(thisrepo)
- except (Errors.RepoError, Errors.ConfigError), e:
- self.errorlog(2, e)
- continue
+ # Check sections in the .repo files that were just slurped up
+ for section in parser.sections():
+ try:
+ thisrepo = config.readRepoConfig(parser, section, self.conf)
+ except (Errors.RepoError, Errors.ConfigError), e:
+ self.errorlog(2, e)
+ else:
+ reposlist.append(thisrepo)
- # got our list of repo objects
+ # Got our list of repo objects, add them to the repos collection
for thisrepo in reposlist:
try:
self.repos.add(thisrepo)
@@ -170,10 +167,10 @@
if hasattr(self, 'read_ts'):
return
- if not self.conf.getConfigOption('installroot'):
+ if not self.conf.installroot:
raise Errors.YumBaseError, 'Setting up TransactionSets before config class is up'
- installroot = self.conf.getConfigOption('installroot')
+ installroot = self.conf.installroot
self.read_ts = rpmUtils.transaction.initReadOnlyTransaction(root=installroot)
self.tsInfo = transactioninfo.TransactionData()
self.rpmdb = rpmUtils.RpmDBHolder()
@@ -205,7 +202,6 @@
"""grabs the repomd.xml for each enabled repository and sets up
the basics of the repository"""
-
self.plugins.run('prereposetup')
repos = []
@@ -221,7 +217,7 @@
if repo.repoXML is not None and len(repo.urls) > 0:
continue
try:
- repo.cache = self.conf.getConfigOption('cache')
+ repo.cache = self.conf.cache
repo.baseurlSetup()
repo.dirSetup()
self.log(3, 'Baseurl(s) for repo: %s' % repo.urls)
@@ -279,17 +275,17 @@
# raise an error
self.up = rpmUtils.updates.Updates(self.rpmdb.getPkgList(),
self.pkgSack.simplePkgList())
- if self.conf.getConfigOption('debuglevel') >= 6:
+ if self.conf.debuglevel >= 6:
self.up.debug = 1
- if self.conf.getConfigOption('obsoletes'):
+ if self.conf.obsoletes:
self.up.rawobsoletes = self.pkgSack.returnObsoletes()
- self.up.exactarch = self.conf.getConfigOption('exactarch')
- self.up.exactarchlist = self.conf.getConfigOption('exactarchlist')
+ self.up.exactarch = self.conf.exactarch
+ self.up.exactarchlist = self.conf.exactarchlist
self.up.doUpdates()
- if self.conf.getConfigOption('obsoletes'):
+ if self.conf.obsoletes:
self.up.doObsoletes()
self.up.condenseUpdates()
@@ -313,7 +309,7 @@
reposWithGroups.append(repo)
# now we know which repos actually have groups files.
- overwrite = self.conf.getConfigOption('overwrite_groups')
+ overwrite = self.conf.overwrite_groups
self.comps = newcomps.Comps(overwrite_groups = overwrite)
for repo in reposWithGroups:
@@ -360,10 +356,10 @@
# if repo: then do only that repos' packages and excludes
if not repo: # global only
- excludelist = self.conf.getConfigOption('exclude')
+ excludelist = self.conf.exclude
repoid = None
else:
- excludelist = repo.excludes
+ excludelist = repo.exclude
repoid = repo.id
if len(excludelist) == 0:
@@ -428,7 +424,7 @@
"""perform the yum locking, raise yum-based exceptions, not OSErrors"""
# if we're not root then we don't lock - just return nicely
- if self.conf.getConfigOption('uid') != 0:
+ if self.conf.uid != 0:
return
root = self.conf.installroot
@@ -461,7 +457,7 @@
"""do the unlock for yum"""
# if we're not root then we don't lock - just return nicely
- if self.conf.getConfigOption('uid') != 0:
+ if self.conf.uid != 0:
return
root = self.conf.installroot
@@ -944,7 +940,7 @@
elif pkgnarrow == 'obsoletes':
self.doRepoSetup()
self.doRpmDBSetup()
- self.conf.setConfigOption('obsoletes', 1)
+ self.conf.obsoletes = 1
self.doUpdateSetup()
for (pkgtup, instTup) in self.up.getObsoletesTuples():
Index: config.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum/config.py,v
retrieving revision 1.77
retrieving revision 1.78
diff -u -r1.77 -r1.78
--- config.py 7 Oct 2005 05:44:53 -0000 1.77
+++ config.py 25 Oct 2005 12:28:44 -0000 1.78
@@ -1,4 +1,5 @@
#!/usr/bin/python -t
+
# 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
@@ -14,128 +15,175 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# Copyright 2002 Duke University
-import ConfigParser
-import sys
[...1146 lines suppressed...]
- continue
- else:
- reposlist.append(thisrepo)
-
- # got our list of repo objects
- reposlist.sort()
- for thisrepo in reposlist:
- try:
- thisrepo.baseurlSetup()
- except Errors.RepoError, e:
- pass
- print thisrepo.dump()
- print ''
-
-if __name__ == "__main__":
- if len(sys.argv) < 2:
- print 'command: config file'
- sys.exit(1)
-
- main(sys.argv[1:])
Index: parser.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum/parser.py,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- parser.py 11 Oct 2005 21:11:03 -0000 1.3
+++ parser.py 25 Oct 2005 12:28:44 -0000 1.4
@@ -6,10 +6,11 @@
import os.path
from ConfigParser import ConfigParser, NoSectionError, NoOptionError
+#TODO: include'ing of URLs (Yum currently supports this)
#TODO: problem: interpolation tokens are lost when config files are rewritten
# - workaround is to not set vars, not sure if this is ok
# - maybe we should do interpolation at the Option level after all?
-#TODO: include'ing of URLs (Yum currently supports this)
+# - preserve original uninterpolated value?
#TODO: separate $var interpolation into YumParser?
class IncludingConfigParser(ConfigParser):
@@ -175,41 +176,22 @@
inc = open(fn, 'w')
self._fns[fn].write(inc)
- _KEYCRE = re.compile(r"\$(\w+)")
-
def _interpolate(self, section, option, rawval, vars):
'''Perform $var subsitution (this overides the default %(..)s subsitution)
Only the rawval and vars arguments are used. The rest are present for
compatibility with the parent class.
'''
- done = [] # Completed chunks to return
-
- while rawval:
- m = self._KEYCRE.search(rawval)
- if not m:
- done.append(rawval)
- break
-
- # Determine replacement value (if unknown variable then preserve original)
- varname = m.group(1).lower()
- replacement = vars.get(varname, m.group())
-
- start, end = m.span()
- done.append(rawval[:start]) # Keep stuff leading up to token
- done.append(replacement) # Append replacement value
- rawval = rawval[end:] # Continue with remainder of string
-
- return ''.join(done)
+ return varReplace(rawval, vars)
class IncludedDirConfigParser(IncludingConfigParser):
"""A conf.d recursive parser - supporting one level of included dirs"""
- def __init__(self, defaults = None, includedir=None, includeglob="*.conf", include="include"):
+ def __init__(self, vars=None, includedir=None, includeglob="*.conf", include="include"):
self.includeglob = includeglob
self.includedir = includedir
- IncludingConfigParser.__init__(self,include=include)
+ IncludingConfigParser.__init__(self, vars=vars, include=include)
def read(self, filenames):
for filename in shlex.split(filenames):
@@ -232,3 +214,29 @@
self._add_include(section, filename)
+_KEYCRE = re.compile(r"\$(\w+)")
+
+def varReplace(raw, vars):
+ '''Perform variable replacement
+
+ @parma
+ '''
+
+ done = [] # Completed chunks to return
+
+ while raw:
+ m = _KEYCRE.search(raw)
+ if not m:
+ done.append(raw)
+ break
+
+ # Determine replacement value (if unknown variable then preserve original)
+ varname = m.group(1).lower()
+ replacement = vars.get(varname, m.group())
+
+ start, end = m.span()
+ done.append(raw[:start]) # Keep stuff leading up to token
+ done.append(replacement) # Append replacement value
+ raw = raw[end:] # Continue with remainder of string
+
+ return ''.join(done)
Index: plugins.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum/plugins.py,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- plugins.py 17 Jul 2005 02:09:16 -0000 1.17
+++ plugins.py 25 Oct 2005 12:28:44 -0000 1.18
@@ -22,6 +22,16 @@
import config
import Errors
+# XXX: break the API for how plugins define config file options
+# - they should just be able to manipulate the YumConf and RepoConf classes
+# directly, adding Option instances as required
+# - cleaner, more flexible and
+# - update PLUGINS document
+# - will take care of the following existing TODOs:
+# TODO: detect conflicts between builtin yum options and registered plugin
+# options (will require refactoring of config.py)
+# TODO: plugins should be able to specify convertor functions for config vars
+
# TODO: should plugin searchpath be affected by installroot option?
# TODO: cleaner method to query installed packages rather than exposing RpmDB
@@ -47,11 +57,6 @@
# TODO: allow plugins to extend commands (on the command line)
-# TODO: plugins should be able to specify convertor functions for config vars
-
-# TODO: detect conflicts between builtin yum options and registered plugin
-# options (will require refactoring of config.py)
-
# TODO: More developer docs: use epydoc as API begins to stablise
# TODO: test the API by implementing some crack from bugzilla
@@ -183,7 +188,8 @@
modname = modname.split('.py')[0]
conf = self._getpluginconf(modname)
- if not conf or not conf._getboolean('main', 'enabled', 0):
+ if not conf or not config.getOption(conf, 'main', 'enabled', False,
+ config.BoolOption()):
self.base.log(3, '"%s" plugin is disabled' % modname)
return
@@ -231,17 +237,16 @@
)
def _getpluginconf(self, modname):
- '''Parse the plugin specific configuration file and return a CFParser
- instance representing it. Returns None if there was an error reading or
- parsing the configuration file.
+ '''Parse the plugin specific configuration file and return a
+ IncludingConfigParser instance representing it. Returns None if there
+ was an error reading or parsing the configuration file.
'''
+ #XXX: should this use installroot?
conffilename = os.path.join('/etc/yum/pluginconf.d', modname+'.conf')
- parser = config.CFParser()
try:
- fin = open(conffilename, 'rt')
- parser.readfp(fin)
- fin.close()
+ parser = config.IncludingConfigParser()
+ parser.read(conffilename)
except ConfigParser.Error, e:
raise Errors.ConfigError("Couldn't parse %s: %s" % (conffilename,
str(e)))
@@ -269,31 +274,33 @@
def parseopts(self, conf, repos):
'''Parse any configuration options registered by plugins
- conf: the yumconf instance holding Yum's global options
- repos: a list of all repository objects
+ @param conf: the yumconf instance holding Yum's global options
+ @param repos: a list of all repository objects
'''
+ #XXX: with the new config stuff this is an ugly hack!
+ # See first TODO at top of this file
+
+ type2opt = {
+ PLUG_OPT_STRING: config.Option(),
+ PLUG_OPT_INT: config.IntOption(),
+ PLUG_OPT_BOOL: config.BoolOption(),
+ PLUG_OPT_FLOAT: config.FloatOption(),
+ }
# Process [main] options first
- self._do_opts(conf.cfg, 'main', PLUG_OPT_WHERE_MAIN,
- conf.setConfigOption)
+ for name, (vtype, where, default) in self.opts.iteritems():
+ if where in (PLUG_OPT_WHERE_MAIN, PLUG_OPT_WHERE_ALL):
+ val = config.getOption(conf.cfg, 'main', name, default,
+ type2opt[vtype])
+ setattr(conf, name, val)
# Process repository level options
for repo in repos:
- self._do_opts(repo.cfgparser, repo.id, PLUG_OPT_WHERE_REPO,
- repo.set)
-
- def _do_opts(self, cfgparser, section, targetwhere, setfunc):
- '''Process registered plugin options for one config file section
- '''
- typetofunc = {
- PLUG_OPT_STRING: cfgparser._getoption,
- PLUG_OPT_INT: cfgparser._getint,
- PLUG_OPT_BOOL: cfgparser._getboolean,
- PLUG_OPT_FLOAT: cfgparser._getfloat,
- }
- for name, (vtype, where, default) in self.opts.iteritems():
- if where in (targetwhere, PLUG_OPT_WHERE_ALL):
- setfunc(name, typetofunc[vtype](section, name, default))
+ for name, (vtype, where, default) in self.opts.iteritems():
+ if where in (PLUG_OPT_WHERE_REPO, PLUG_OPT_WHERE_ALL):
+ val = config.getOption(conf.cfg, repo.id, name, default,
+ type2opt[vtype])
+ repo.set(name, val)
def setCmdLine(self, opts, commands):
'''Set the parsed command line options so that plugins can access them
@@ -326,7 +333,7 @@
def promptYN(self, msg):
self.info(2, msg)
- if self._base.conf.getConfigOption('assumeyes'):
+ if self._base.conf.assumeyes:
return 1
else:
return self._base.userconfirm()
@@ -360,7 +367,8 @@
@param default: Value to read if option is missing.
@return: String option value read, or default if option was missing.
'''
- return self._conf._getoption(section, opt, default)
+ return config.getoption(self._conf, section, opt, default,
+ config.Option())
def confInt(self, section, opt, default=None):
'''Read an integer value from the plugin's own configuration file
@@ -371,7 +379,8 @@
@return: Integer option value read, or default if option was missing or
could not be parsed.
'''
- return self._conf._getint(section, opt, default)
+ return config.getoption(self._conf, section, opt, default,
+ config.IntOption())
def confFloat(self, section, opt, default=None):
'''Read a float value from the plugin's own configuration file
@@ -382,7 +391,8 @@
@return: Float option value read, or default if option was missing or
could not be parsed.
'''
- return self._conf._getfloat(section, opt, default)
+ return config.getoption(self._conf, section, opt, default,
+ config.FloatOption())
def confBool(self, section, opt, default=None):
'''Read a boolean value from the plugin's own configuration file
@@ -393,7 +403,8 @@
@return: Boolean option value read, or default if option was missing or
could not be parsed.
'''
- return self._conf._getboolean(section, opt, default)
+ return config.getoption(self._conf, section, opt, default,
+ config.BoolOption())
class ConfigPluginConduit(PluginConduit):
Index: repos.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum/repos.py,v
retrieving revision 1.83
retrieving revision 1.84
diff -u -r1.83 -r1.84
--- repos.py 8 Aug 2005 14:57:05 -0000 1.83
+++ repos.py 25 Oct 2005 12:28:44 -0000 1.84
@@ -30,6 +30,7 @@
from repomd import packageSack
from packages import YumAvailablePackage
import mdcache
+import parser
_is_fnmatch_pattern = re.compile(r"[*?[]").search
@@ -332,9 +333,9 @@
self.cache = 0
self.callback = None # callback for the grabber
self.failure_obj = None
- self.mirrorlistfn = None # filename/url of mirrorlist file
+ self.mirrorlist = None # filename/url of mirrorlist file
self.mirrorlistparsed = 0
- self.baseurls = [] # baseurls from the config file
+ self.baseurl = [] # baseurls from the config file
self.yumvar = {} # empty dict of yumvariables for $string replacement
self.proxy_password = None
self.proxy_username = None
@@ -401,8 +402,8 @@
output = '[%s]\n' % self.id
vars = ['name', 'bandwidth', 'enabled', 'enablegroups',
'gpgcheck', 'includepkgs', 'keepalive', 'proxy',
- 'proxy_password', 'proxy_username', 'excludes',
- 'retries', 'throttle', 'timeout', 'mirrorlistfn',
+ 'proxy_password', 'proxy_username', 'exclude',
+ 'retries', 'throttle', 'timeout', 'mirrorlist',
'cachedir', 'gpgkey', 'pkgdir', 'hdrdir']
vars.sort()
for attr in vars:
@@ -524,15 +525,15 @@
with valid ones, run self.check() at the end to make sure it worked"""
goodurls = []
- if self.mirrorlistfn and not self.mirrorlistparsed:
- mirrorurls = getMirrorList(self.mirrorlistfn)
+ if self.mirrorlist and not self.mirrorlistparsed:
+ mirrorurls = getMirrorList(self.mirrorlist)
self.mirrorlistparsed = 1
for url in mirrorurls:
- url = variableReplace(self.yumvar, url)
- self.baseurls.append(url)
-
- for url in self.baseurls:
- url = variableReplace(self.yumvar, url)
+ url = parser.varReplace(url, self.yumvar)
+ self.baseurl.append(url)
+
+ for url in self.baseurl:
+ url = parser.varReplace(url, self.yumvar)
(s,b,p,q,f,o) = urlparse.urlparse(url)
if s not in ['http', 'ftp', 'file', 'https']:
print 'not using ftp, http[s], or file for repos, skipping - %s' % (url)
@@ -814,46 +815,3 @@
return returnlist
-def variableReplace(yumvar, thing):
- """ do the replacement of $ variables, releasever, arch and basearch on any
- string or list passed to it - returns whatever you passed"""
-
- if thing is None:
- return thing
-
- elif type(thing) is types.ListType:
- shortlist = thing
-
- elif type(thing) is types.StringType:
- shortlist = []
- shortlist.append(thing)
-
- else:
- # not a list or string, screw it
- return thing
-
- basearch_reg = re.compile('\$basearch', re.I)
- arch_reg = re.compile('\$arch', re.I)
- releasever_reg = re.compile('\$releasever', re.I)
- yumvar_reg = {}
-
- for num in range(0,10):
- env = '\$YUM%s' % num
- yumvar_reg[num] = re.compile(env, re.I)
-
- returnlist = []
- for string in shortlist:
- (string, count) = basearch_reg.subn(yumvar['basearch'], string)
- (string, count) = arch_reg.subn(yumvar['arch'], string)
- (string, count) = releasever_reg.subn(yumvar['releasever'], string)
- for num in range(0,10):
- (string, count) = yumvar_reg[num].subn(yumvar[num], string)
- returnlist.append(string)
-
- if type(thing) is types.StringType:
- thing = returnlist[0]
-
- if type(thing) is types.ListType:
- thing = returnlist
-
- return thing
More information about the Yum-cvs-commits
mailing list