[yum-cvs] yum/yum __init__.py, 1.205, 1.206 config.py, 1.97, 1.98 plugins.py, 1.24, 1.25
Menno Smits
mjs at linux.duke.edu
Sun Jun 4 19:48:39 UTC 2006
Update of /home/groups/yum/cvs/yum/yum
In directory login1.linux.duke.edu:/tmp/cvs-serv3712/yum
Modified Files:
__init__.py config.py plugins.py
Log Message:
Allow plugins to add and manipulate Yum's configuration file options in the
same way as they are defined in Yum. This means that plugin option defines are
far more flexible and powerful than before. The old API (registerOpt) still
exists but is deprecated (with a saner implementation). I will update the wiki
with info on how plugins can now define their own options.
This cleans up a lot of plugin related code but changes the Yum API slightly
wrt to initialisation. Documentation about this to come on yum-devel.
This commit also includes Misa's (misa+yum at redhat.com) patch to add a config
option for specifying the directories to look in for plugin configuration
files.
Index: __init__.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum/__init__.py,v
retrieving revision 1.205
retrieving revision 1.206
diff -u -r1.205 -r1.206
--- __init__.py 30 May 2006 10:15:41 -0000 1.205
+++ __init__.py 4 Jun 2006 19:48:37 -0000 1.206
@@ -88,6 +88,7 @@
"""do a default setup for all the normal/necessary yum components,
really just a shorthand for testing"""
+ self.doStartupConfig()
self.doConfigSetup()
self.conf.cache = cache
self.doTsSetup()
@@ -95,10 +96,15 @@
self.doRepoSetup()
self.doSackSetup()
- def doConfigSetup(self, fn='/etc/yum.conf', root='/'):
+ def doStartupConfig(self, fn='/etc/yum.conf', root='/'):
+ '''Read up configuration options required early during startup.
+ '''
+ self.startupconf = config.readStartupConfig(fn, root)
+
+ def doConfigSetup(self):
"""basic stub function for doing configuration setup"""
-
- self.conf = config.readMainConfig(fn, root)
+
+ self.conf = config.readMainConfig(self.startupconf)
self.yumvar = self.conf.yumvar
self.getReposFromConfig()
@@ -161,8 +167,9 @@
def doPluginSetup(self, optparser=None, types=None):
'''Initialise and enable yum plugins.
- If plugins are going to be used, this should be called soon after
- doConfigSetup() has been called.
+ This should be called after doStartupConfig() has been called but
+ before doConfigSetup() so that plugins can modify Yum's configuration
+ option definitions.
@param optparser: The OptionParser instance for this run (optional)
@param types: A sequence specifying the types of plugins to load.
@@ -170,13 +177,9 @@
yum.plugins.TYPE_... constants. If None (the default), all plugins
will be loaded.
'''
- # Load plugins first as they make affect available config options
- self.plugins = plugins.YumPlugins(self, self.conf.pluginpath,
+ self.plugins = plugins.YumPlugins(self, self.startupconf.pluginpath,
optparser, types)
- # Process options registered by plugins
- self.plugins.parseopts(self.conf, self.repos.findRepos('*'))
-
# Initialise plugins
self.plugins.run('init')
Index: config.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum/config.py,v
retrieving revision 1.97
retrieving revision 1.98
diff -u -r1.97 -r1.98
--- config.py 11 Apr 2006 21:37:23 -0000 1.97
+++ config.py 4 Jun 2006 19:48:37 -0000 1.98
@@ -465,24 +465,29 @@
else:
raise Errors.ConfigError, 'No such option %s' % option
-class EarlyConf(BaseConfig):
+class StartupConf(BaseConfig):
'''
Configuration option definitions for yum.conf's [main] section that are
- required before the other [main] options can be parsed (mainly due to
- variable substitution).
+ required early in the initialisation process or before the other [main]
+ options can be parsed.
'''
+ debuglevel = IntOption(2)
+ errorlevel = IntOption(2)
+
distroverpkg = Option('fedora-release')
installroot = Option('/')
-class YumConf(EarlyConf):
+ plugins = BoolOption(False)
+ pluginpath = ListOption(['/usr/lib/yum-plugins'])
+ pluginconfpath = ListOption(['/etc/yum/pluginconf.d'])
+
+class YumConf(StartupConf):
'''
Configuration option definitions for yum.conf\'s [main] section.
- Note: inherits options from EarlyConf too.
+ Note: see also options inherited from StartupConf
'''
- debuglevel = IntOption(2)
- errorlevel = IntOption(2)
retries = IntOption(10)
recent = IntOption(7)
@@ -500,7 +505,6 @@
proxy = UrlOption(schemes=('http', 'ftp', 'https'), allow_none=True)
proxy_username = Option()
proxy_password = Option()
- pluginpath = ListOption(['/usr/lib/yum-plugins'])
installonlypkgs = ListOption(['kernel', 'kernel-bigmem',
'kernel-enterprise','kernel-smp', 'kernel-modules', 'kernel-debug',
'kernel-unsupported', 'kernel-source', 'kernel-devel'])
@@ -522,7 +526,6 @@
obsoletes = BoolOption(False)
showdupesfromrepos = BoolOption(False)
enabled = BoolOption(True)
- plugins = BoolOption(False)
enablegroups = BoolOption(True)
enable_group_conditionals = BoolOption(True)
@@ -562,48 +565,62 @@
http_caching = Inherit(YumConf.http_caching)
metadata_expire = Inherit(YumConf.metadata_expire)
-def readMainConfig(configfile, root):
- '''Parse Yum's main configuration file
+def readStartupConfig(configfile, root):
+ '''
+ Parse Yum's main configuration file and return a StartupConf instance.
+
+ This is required in order to access configuration settings required as Yum
+ starts up.
- @param configfile: Path to the configuration file to parse (typically
- '/etc/yum.conf').
+ @param configfile: The path to yum.conf.
@param root: The base path to use for installation (typically '/')
- @return: Populated YumConf instance.
- '''
+ @return: A StartupConf instance.
- # Read up config variables that are needed early to calculate substitution
- # variables
- EarlyConf.installroot.default = root
- earlyconf = EarlyConf()
- confparser = IncludingConfigParser()
+ May raise Errors.ConfigError if a problem is detected with while parsing.
+ '''
if not os.path.exists(configfile):
raise Errors.ConfigError, 'No such config file %s' % configfile
- confparser.read(configfile)
- earlyconf.populate(confparser, 'main')
+ StartupConf.installroot.default = root
+ startupconf = StartupConf()
+
+ parser = IncludingConfigParser()
+ parser.read(configfile)
+ startupconf.populate(parser, 'main')
+ # Check that plugin paths are all absolute
+ for path in startupconf.pluginpath:
+ if not path.startswith('/'):
+ raise Errors.ConfigError("All plugin search paths must be absolute")
+
+ # Stuff this here to avoid later re-parsing
+ startupconf._parser = parser
+
+ return startupconf
+
+def readMainConfig(startupconf):
+ '''
+ Parse Yum's main configuration file
+
+ @param startupconf: StartupConf instance as returned by readStartupConfig()
+ @return: Populated YumConf instance.
+ '''
+
# Set up substitution vars
vars = _getEnvVar()
vars['basearch'] = rpmUtils.arch.getBaseArch() # FIXME make this configurable??
vars['arch'] = rpmUtils.arch.getCanonArch() # FIXME make this configurable??
- vars['releasever'] = _getsysver(earlyconf.installroot, earlyconf.distroverpkg)
+ vars['releasever'] = _getsysver(startupconf.installroot, startupconf.distroverpkg)
# Read [main] section
yumconf = YumConf()
- confparser = IncludingConfigParser(vars=vars)
- confparser.read(configfile)
- yumconf.populate(confparser, 'main')
+ yumconf.populate(startupconf._parser, 'main')
# Apply the installroot to directory options
for option in ('cachedir', 'logfile'):
path = getattr(yumconf, option)
setattr(yumconf, option, yumconf.installroot + path)
- # Check that plugin paths are all absolute
- for path in yumconf.pluginpath:
- if not path.startswith('/'):
- raise Errors.ConfigError("All plugin search paths must be absolute")
-
# Add in some extra attributes which aren't actually configuration values
yumconf.yumvar = vars
yumconf.uid = 0
@@ -645,14 +662,13 @@
return thisrepo
-def getOption(conf, section, name, default, option):
+def getOption(conf, section, name, option):
'''Convenience function to retrieve a parsed and converted value from a
ConfigParser.
@param conf: ConfigParser instance or similar
@param section: Section name
@param name: Option name
- @param default: Value to use if option is missing
@param option: Option instance to use for conversion.
@return: The parsed value or default if value was not present.
@@ -661,7 +677,7 @@
try:
val = conf.get(section, name)
except (NoSectionError, NoOptionError):
- return default
+ return option.default
return option.parse(val)
def _getEnvVar():
@@ -699,7 +715,6 @@
del ts
return releasever
-
#def main():
# mainconf = readMainConfig('/etc/yum.conf', '/')
# repoconf = readRepoConfig(mainconf.cfg, 'core', mainconf)
Index: plugins.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum/plugins.py,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- plugins.py 11 May 2006 21:06:18 -0000 1.24
+++ plugins.py 4 Jun 2006 19:48:37 -0000 1.25
@@ -23,20 +23,7 @@
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
-# (Panu?)
+# TODO: expose rpm package sack objects to plugins (once finished)
# TODO: consistent case of YumPlugins methods
@@ -51,9 +38,6 @@
# TODO: multiversion plugin support
-# TODO: config vars marked as PLUG_OPT_WHERE_ALL should inherit defaults from
-# the [main] setting if the user doesn't specify them
-
# TODO: allow plugins to extend shell commands
# TODO: allow plugins to extend commands (on the command line)
@@ -75,7 +59,7 @@
# API, the major version number must be incremented and the minor version number
# reset to 0. If a change is made that doesn't break backwards compatibility,
# then the minor number must be incremented.
-API_VERSION = '2.3'
+API_VERSION = '2.4'
class DeprecatedInt(int):
'''
@@ -142,7 +126,6 @@
self._importplugins(types)
- self.opts = {}
self.cmdlines = {}
# Call close handlers when yum exit's
@@ -192,8 +175,8 @@
modname = modname.split('.py')[0]
conf = self._getpluginconf(modname)
- if not conf or not config.getOption(conf, 'main', 'enabled', False,
- config.BoolOption()):
+ if not conf or not config.getOption(conf, 'main', 'enabled',
+ config.BoolOption(False)):
self.base.log(3, '"%s" plugin is disabled' % modname)
return
@@ -250,8 +233,18 @@
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')
+ for dir in self.base.startupconf.pluginconfpath:
+ conffilename = os.path.join(dir, modname + ".conf")
+ if os.access(conffilename, os.R_OK):
+ # Found configuration file
+ break
+ self.base.log(3, "Configuration file %s not found" % conffilename)
+ else: # for
+ # Configuration files for the plugin not found
+ self.base.log(2, "Unable to find configuration file for plugin %s"
+ % modname)
+ return None
+
try:
parser = config.IncludingConfigParser()
@@ -265,52 +258,6 @@
return parser
- def registeropt(self, name, valuetype, where, default):
- '''Called from plugins to register a new config file option.
-
- @param name: Name of the new option.
- @param valuetype: Option type (PLUG_OPT_BOOL, PLUG_OPT_STRING ...)
- @param where: Where the option should be available in the config file.
- (PLUG_OPT_WHERE_MAIN, PLUG_OPT_WHERE_REPO, ...)
- @param default: Default value for the option if not set by the user.
- '''
- if self.opts.has_key(name):
- raise Errors.ConfigError('Plugin option conflict: ' \
- 'an option named "%s" has already been registered' % name
- )
- self.opts[name] = (valuetype, where, default)
-
- def parseopts(self, conf, repos):
- '''Parse any configuration options registered by plugins
-
- @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
- 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:
- for name, (vtype, where, default) in self.opts.iteritems():
- if where in (PLUG_OPT_WHERE_REPO, PLUG_OPT_WHERE_ALL):
- val = config.getOption(repo.cfg, repo.id, name, default,
- type2opt[vtype])
- repo.setAttribute(name, val)
-
def setCmdLine(self, opts, commands):
'''Set the parsed command line options so that plugins can access them
'''
@@ -376,8 +323,7 @@
@param default: Value to read if option is missing.
@return: String option value read, or default if option was missing.
'''
- return config.getOption(self._conf, section, opt, default,
- config.Option())
+ return config.getOption(self._conf, section, opt, config.Option(default))
def confInt(self, section, opt, default=None):
'''Read an integer value from the plugin's own configuration file
@@ -388,8 +334,7 @@
@return: Integer option value read, or default if option was missing or
could not be parsed.
'''
- return config.getOption(self._conf, section, opt, default,
- config.IntOption())
+ return config.getOption(self._conf, section, opt, config.IntOption(default))
def confFloat(self, section, opt, default=None):
'''Read a float value from the plugin's own configuration file
@@ -400,8 +345,7 @@
@return: Float option value read, or default if option was missing or
could not be parsed.
'''
- return config.getOption(self._conf, section, opt, default,
- config.FloatOption())
+ return config.getOption(self._conf, section, opt, config.FloatOption(default))
def confBool(self, section, opt, default=None):
'''Read a boolean value from the plugin's own configuration file
@@ -412,18 +356,40 @@
@return: Boolean option value read, or default if option was missing or
could not be parsed.
'''
- return config.getOption(self._conf, section, opt, default,
- config.BoolOption())
+ return config.getOption(self._conf, section, opt, config.BoolOption(default))
class ConfigPluginConduit(PluginConduit):
- def registerOpt(self, *args, **kwargs):
+ def registerOpt(self, name, valuetype, where, default):
'''Register a yum configuration file option.
- Arguments are as for YumPlugins.registeropt().
+ @param name: Name of the new option.
+ @param valuetype: Option type (PLUG_OPT_BOOL, PLUG_OPT_STRING ...)
+ @param where: Where the option should be available in the config file.
+ (PLUG_OPT_WHERE_MAIN, PLUG_OPT_WHERE_REPO, ...)
+ @param default: Default value for the option if not set by the user.
'''
- self._parent.registeropt(*args, **kwargs)
+ warnings.warn('registerOpt() will go away in a future version of Yum.\n'
+ 'Please manipulate config.YumConf and config.RepoConf directly.'
+ DeprecationWarning)
+
+ type2opt = {
+ PLUG_OPT_STRING: config.Option,
+ PLUG_OPT_INT: config.IntOption,
+ PLUG_OPT_BOOL: config.BoolOption,
+ PLUG_OPT_FLOAT: config.FloatOption,
+ }
+
+ if where == PLUG_OPT_WHERE_MAIN:
+ setattr(config.YumConf, name, type2opt[valuetype](default))
+
+ elif where == PLUG_OPT_WHERE_REPO:
+ setattr(config.RepoConf, name, type2opt[valuetype](default))
+ elif where == PLUG_OPT_WHERE_ALL:
+ option = type2opt[valuetype](default)
+ setattr(config.YumConf, name, option)
+ setattr(config.RepoConf, name, config.inhert(option))
class InitPluginConduit(PluginConduit):
More information about the Yum-cvs-commits
mailing list