[yum-cvs] yum/yum plugins.py, NONE, 1.1 __init__.py, 1.98, 1.99 config.py, 1.49, 1.50 constants.py, 1.1, 1.2
Menno Smits
mjs at login.linux.duke.edu
Mon Mar 21 12:37:15 UTC 2005
Update of /home/groups/yum/cvs/yum/yum
In directory login:/tmp/cvs-serv19726/yum
Modified Files:
__init__.py config.py constants.py
Added Files:
plugins.py
Log Message:
Initial yum plugin work.
--- NEW FILE plugins.py ---
import os
import glob
import imp
import atexit
from constants import *
# TODO: API version checking
# - multiversion plugin support?
# TODO: prefix for slot methods ("yum_"?) so that yum knows if plugin is trying
# to hook into something that it doesn't support (eg. new plugin with older yum
# version)
# TODO: move all config hooks to within yum pacakge (not cli.py). This may
# require some minor refactoring of various yum bits.
# TODO: better documentation of how the whole thing works (esp. addition of
# config options)
# TODO: use exception in plugins to signal that yum should abort instead of
# return codes
# TODO: fix log() during yum init: early calls to log() (before Logger instance
# is created) mean that all output goes to stdout regardless of the log settings.
# TODO: reposetup slot: plugin must be able to enable and disable repos
# TODO: make it that plugins need to be expicity enabled so that software using
# yum as a library doesn't get expected plugin interference?
# TODO: cmd line options to disable plugins (all or specific)
# TODO: cmdline/config option to specify additional plugin directories (plugin path)
# TODO: config vars marked as PLUG_OPT_WHERE_ALL should inherit defaults from
# the [main] setting if the user doesn't specify them
# TODO: handling of plugins that define options which collide with other
# plugins or builtin yum options
# TODO: plugins should be able to specify convertor functions for config vars
# TODO: investigate potential issues with plugins doing user output during
# their close handlers, esp wrt GUI apps
# TODO "log" slot? To allow plugins to do customised logging/history (say to a
# SQL db)
# TODO: require an explicit call to load plugins so that software using yum as
# a # library doesn't get nasty suprises
SLOTS = ('config', 'init', 'exclude', 'pretrans', 'posttrans', 'close')
class YumPlugins:
def __init__(self, base, dir):
self.dir = dir
self.base = base
self._importplugins()
self.opts = []
# Call close handlers when yum exit's
atexit.register(self.run, 'close')
# Let plugins register custom config file options
self.run('config')
def run(self, slotname):
'''Run all plugin functions for the given slot.
Returns true if yum needs to quit, false otherwise.
'''
# Determine handler class to use
if slotname in ('config'):
gwcls = ConfigPluginConduit
elif slotname == 'init':
gwcls = InitPluginConduit
elif slotname == 'close':
gwcls = PluginConduit
elif slotname in ('pretrans', 'posttrans', 'exclude'):
gwcls = MainPluginConduit
else:
raise ValueError('unknown slot name "%s"' % slotname)
gw = gwcls(self, self.base)
for modname, func in self._pluginfuncs[slotname]:
self.base.log(4, 'Running %s handler for %s plugin' % (
slotname, modname))
result = func(gw)
if result:
# Plugin said we need to terminate
self.base.log(2, "Exiting due to '%s' plugin." % modname)
return result
return 0
def _importplugins(self):
# Initialise plugin dict
self._plugins = {}
self._pluginfuncs = {}
for slot in SLOTS:
self._pluginfuncs[slot] = []
# Import plugins and collect plugin calls for each slot
for module in glob.glob('%s/*.py' % self.dir):
modname = os.path.basename(module).split('.py')[0]
self.base.log(2, 'Loading %s plugin' % modname)
fp, pathname, description = imp.find_module(modname, [self.dir])
module = imp.load_module(modname, fp, pathname, description)
#TODO: check API version here?
self._plugins[modname] = module
for slot in SLOTS:
if hasattr(module, slot):
self._pluginfuncs[slot].append(
(modname, getattr(module, slot))
)
def registeropt(self, name, valuetype, where, default):
'''Called from plugins to register a new config file option.
name: Name of the new option.
valuetype: Option type (PLUG_OPT_BOOL, PLUG_OPT_STRING ...)
where: Where the option should be available in the config file.
(PLUG_OPT_WHERE_GLOBAL, PLUG_OPT_WHERE_REPO, ...)
default: Default value for the option if not set by the user.
'''
#TODO: duplicate detection
self.opts.append((name, valuetype, where, default))
def getopts(self, targetwhere):
'''Retrieve plugin defined options for the given part of the
configuration file.
targetwhere: the type of option wanted. Should be
PLUG_OPT_WHERE_GLOBAL, PLUG_OPT_WHERE_REPO or PLUG_OPT_WHERE_ALL
return: A list of (name, value_type, default) tuples.
'''
out = []
for name, valuetype, where, default in self.opts:
if where == targetwhere or where == PLUG_OPT_WHERE_ALL:
out.append((name, valuetype, default))
return out
class PluginConduit:
def __init__(self, parent, base):
self._parent = parent
self._base = base
def info(self, level, msg):
self._base.log(level, msg)
def error(self, level, msg):
self._base.errorlog(level, msg)
def promptyn(self, msg):
self.info(2, msg)
if self._base.conf.getConfigOption('assumeyes'):
return 1
else:
return self._base.userconfirm()
class ConfigPluginConduit(PluginConduit):
def registeropt(self, *args, **kwargs):
self._parent.registeropt(*args, **kwargs)
class InitPluginConduit(PluginConduit):
def getConf(self):
return self._base.conf
class MainPluginConduit(InitPluginConduit):
def getRepos(self):
return self._base.repos.listEnabled()
def getPackages(self, repo=None):
if repo:
arg = repo.id
else:
arg = None
return self._base.pkgSack.returnPackages(arg)
def delPackage(self, po):
self._base.pkgSack.delPackage(po)
def getTsInfo(self):
return self._base.tsInfo
Index: __init__.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum/__init__.py,v
retrieving revision 1.98
retrieving revision 1.99
diff -u -r1.98 -r1.99
--- __init__.py 15 Mar 2005 07:33:19 -0000 1.98
+++ __init__.py 21 Mar 2005 12:37:13 -0000 1.99
@@ -37,6 +37,7 @@
import transactioninfo
from urlgrabber.grabber import URLGrabError
import depsolve
+import plugins
from packages import parsePackages, YumLocalPackage, YumInstalledPackage, bestPackage
from repomd import mdErrors
@@ -64,13 +65,22 @@
def filelog(self, value, msg):
print msg
-
- def doConfigSetup(self, fn='/etc/yum.conf', root='/'):
+
+ def doConfigSetup(self, fn='/etc/yum.conf', root='/',
+ plugindir='/usr/lib/yum-plugins'):
"""basic stub function for doing configuration setup"""
-
- self.conf = config.yumconf(configfile=fn, root=root)
+
+ # Load plugins first as they make affect available config options
+ self.plugins = plugins.YumPlugins(self, plugindir)
+
+ self.conf = config.yumconf(configfile=fn, root=root,
+ plugins=self.plugins)
self.getReposFromConfig()
+ # Initialise plugins
+ if self.plugins.run('init') != 0:
+ sys.exit()
+
def getReposFromConfig(self):
"""read in repositories from config main and .repo files"""
@@ -207,6 +217,8 @@
for repo in self.repos.listEnabled():
self.excludePackages(repo)
self.includePackages(repo)
+ if self.plugins.run('exclude') != 0:
+ sys.exit()
self.pkgSack.buildIndexes()
def doUpdateSetup(self):
@@ -308,7 +320,7 @@
for po in exactmatch + matched:
self.log(3, 'Excluding %s' % po)
self.pkgSack.delPackage(po)
-
+
self.log(2, 'Finished')
def includePackages(self, repo):
Index: config.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum/config.py,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -r1.49 -r1.50
--- config.py 15 Mar 2005 07:43:03 -0000 1.49
+++ config.py 21 Mar 2005 12:37:13 -0000 1.50
@@ -33,6 +33,8 @@
import urlgrabber.grabber
from repos import variableReplace, Repository
+from constants import *
+
class CFParser(ConfigParser.ConfigParser):
"""wrapper around ConfigParser to provide two simple but useful functions:
@@ -171,7 +173,7 @@
class yumconf(object):
"""primary config class for yum"""
- def __init__(self, configfile = '/etc/yum.conf', root='/'):
+ def __init__(self, configfile = '/etc/yum.conf', root='/', plugins=None):
self.cfg = CFParser()
configh = confpp(configfile)
try:
@@ -181,7 +183,7 @@
except ConfigParser.ParsingError, e:
raise Errors.ConfigError, str(e)
-
+ self.plugins = plugins
self.configdata = {} # dict to hold all the data goodies
@@ -238,7 +240,6 @@
optionfloats = [('timeout', 30.0)]
-
# do these two early so we can do the rest using variableReplace()
for (option, default) in [('distroverpkg' , 'fedora-release'),
('installroot', root)]:
@@ -327,6 +328,11 @@
for option in ['exclude', 'installonlypkgs', 'kernelpkgnames', 'tsflags']:
self.configdata[option] = parseList(self.configdata[option])
+
+ # Process options from plugins
+ dopluginopts(self.plugins, self.cfg, 'main', PLUG_OPT_WHERE_GLOBAL,
+ self.setConfigOption)
+
def listConfigOptions(self):
"""return list of options available for global config"""
return self.configdata.keys()
@@ -410,7 +416,6 @@
Returns a repos.Repository object
"""
-
thisrepo = Repository(section)
thisrepo.set('yumvar', yumconfig.yumvar)
@@ -470,6 +475,10 @@
thisrepo.set('pkgdir', pkgdir)
thisrepo.set('hdrdir', hdrdir)
+ # Process options from plugins
+ dopluginopts(yumconfig.plugins, cfgparser, section, PLUG_OPT_WHERE_REPO,
+ thisrepo.set)
+
return thisrepo
@@ -489,7 +498,19 @@
(value, count) = commarepl.subn(' ', value)
listvalue = value.split()
return listvalue
-
+
+def dopluginopts(plugins, cfgparser, section, where, setfunc):
+ '''Process options from plugins
+ '''
+ if plugins:
+ typetofunc = {
+ PLUG_OPT_STRING: cfgparser._getoption,
+ PLUG_OPT_INT: cfgparser._getint,
+ PLUG_OPT_BOOL: cfgparser._getboolean,
+ PLUG_OPT_FLOAT: cfgparser._getfloat,
+ }
+ for name, vtype, default in plugins.getopts(where):
+ setfunc(name, typetofunc[vtype](section, name, default))
class confpp:
Index: constants.py
===================================================================
RCS file: /home/groups/yum/cvs/yum/yum/constants.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- constants.py 12 Mar 2005 22:13:15 -0000 1.1
+++ constants.py 21 Mar 2005 12:37:13 -0000 1.2
@@ -39,3 +39,13 @@
SYMBOLFLAGS = {'>':'GT', '<':'LT', '=': 'EQ', '==': 'EQ', '>=':'GE', '<=':'LE'}
LETTERFLAGS = {'GT':'>', 'LT':'<', 'EQ':'=', 'GE': '>=', 'LE': '<='}
+# Constants for plugin config option registration
+PLUG_OPT_STRING = 0
+PLUG_OPT_INT = 1
+PLUG_OPT_FLOAT = 2
+PLUG_OPT_BOOL = 3
+
+PLUG_OPT_WHERE_GLOBAL = 0
+PLUG_OPT_WHERE_REPO = 1
+PLUG_OPT_WHERE_ALL = 2
+
More information about the Yum-cvs-commits
mailing list