From 321e1d752c220f11465cf047c8af322a03eff9f8 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Tue, 12 Mar 2013 03:30:04 +0100 Subject: Plugins/Packages/Layman: add support for layman overlays In combination with the PortageCollection the Packages plugin could now handle layman overlays. The Portage collection evaluates the dependencies with respect to the configured overlays. --- src/lib/Bcfg2/Server/Plugins/Packages/Layman.py | 115 +++++++++++++++++++++++ src/lib/Bcfg2/Server/Plugins/Packages/Portage.py | 8 ++ 2 files changed, 123 insertions(+) create mode 100644 src/lib/Bcfg2/Server/Plugins/Packages/Layman.py (limited to 'src') diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Layman.py b/src/lib/Bcfg2/Server/Plugins/Packages/Layman.py new file mode 100644 index 000000000..40358e214 --- /dev/null +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Layman.py @@ -0,0 +1,115 @@ +import os +import layman +import Bcfg2.Server.Plugin + +class LaymanSource(Bcfg2.Server.Plugin.Debuggable): + basegroups = ['portage', 'gentoo', 'emerge'] + ptype = 'layman' + cclass = 'Portage' + + def __init__(self, basepath, xsource, config): + Bcfg2.Server.Plugin.Debuggable.__init__(self) + self.basepath = basepath + self.xsource = xsource + self.config = config + + self.url = xsource.get('url', 'http://www.gentoo.org/proj/en/overlays/repositories.xml') + self.name = xsource.get('name', '') + self.priority = xsource.get('priority', 0) + self.cachefile = None + self.gpgkeys = [] + self.recommended = False + + # configure layman + base = os.path.join(basepath, 'layman') + config = layman.config.OptionConfig(options = { + 'storage': os.path.join(base, 'overlays'), + 'cache': os.path.join(base, 'cache'), + 'installed': os.path.join(base, 'installed.xml'), + 'local_list': os.path.join(base, 'overlays.xml'), + 'overlays': [url] + }) + self.api = layman.LaymanAPI(config) + + # path + self.dir = os.path.join(basepath, 'overlays', self.name) + + # build the set of conditions to see if this source applies to + # a given set of metadata + self.conditions = [] + self.groups = [] # provided for some limited backwards compat + for el in xsource.iterancestors(): + if el.tag == "Group": + if el.get("negate", "false").lower() == "true": + self.conditions.append(lambda m, el=el: + el.get("name") not in m.groups) + else: + self.groups.append(el.get("name")) + self.conditions.append(lambda m, el=el: + el.get("name") in m.groups) + elif el.tag == "Client": + if el.get("negate", "false").lower() == "true": + self.conditions.append(lambda m, el=el: + el.get("name") != m.hostname) + else: + self.conditions.append(lambda m, el=el: + el.get("name") == m.hostname) + + def save_state(self): + pass + + def load_state(self): + pass + + def filter_unknown(self, unknown): + filtered = set([u for u in unknown if u.startswith('choice')]) + unknown.difference_update(filtered) + + def get_urls(self): + return self.url + urls = property(get_urls) + + def magic_groups_match(self, metadata): + if self.config.getboolean("global", "magic_groups", + default=True) == False: + return True + else: + for group in self.basegroups: + if group in metadata.groups: + return True + return False + + def setup_data(self, force_update=False): + self.api.fetch_remote_list() + if not self.api.is_repo(self.name): + self.logger.error("Packages: Layman overlay '%s' not" + " found" % self.name) + return False + + if not self.api.is_installed(self.name): + self.logger.info("Packages: Adding layman overlay '%s'" % + self.name) + if not self.api.add_repos(name): + self.logger.error("Packages: Failed adding layman" + " overlay '%s'" % self.name) + return False + + if force_update: + if not self.api.sync(name): + self.logger.error("Packages: Failed syncing layman" + " overlay '%s'" % self.name) + return False + + return True + + def applies(self, metadata): + # check base groups + if not self.magic_groups_match(metadata): + return False + + # check Group/Client tags from sources.xml + for condition in self.conditions: + if not condition(metadata): + return False + + return True diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Portage.py b/src/lib/Bcfg2/Server/Plugins/Packages/Portage.py index 934619500..02bcfa5a2 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Portage.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Portage.py @@ -5,6 +5,7 @@ import os import lxml.etree import Bcfg2.Server.Plugin from Bcfg2.Server.Plugins.Packages.Collection import Collection +from Bcfg2.Server.Plugins.Packages.Layman import LaymanSource _portage_python = '/usr/lib/portage/pym/' @@ -170,6 +171,13 @@ class PortageCollection(Collection): env = portage.settings.configdict['backupenv'] + # add layman overlays + env['PORTDIR_OVERLAY'] = '' + for overlay in self.sources: + if isinstance(overlay, LaymanSource): + env['PORTDIR_OVERLAY'] += ' ' + env['PORTDIR_OVERLAY'] += overlay.dir + portage.settings = portage.package.ebuild.config.config( config_root=portage.settings['PORTAGE_CONFIGROOT'], target_root=portage.settings['ROOT'], -- cgit v1.2.3-1-g7c22