diff options
author | Alexander Sulfrian <alexander@sulfrian.net> | 2013-03-12 03:30:04 +0100 |
---|---|---|
committer | Alexander Sulfrian <alexander@sulfrian.net> | 2014-02-26 13:38:17 +0100 |
commit | 784f1580709eae996134923b9fd5f557202d59cb (patch) | |
tree | b6946cfe651d858d5479598c06e4c94db277d632 /src/lib/Bcfg2/Server/Plugins | |
parent | 9e5645f95fe5deedae084f371509888e514e19b0 (diff) | |
download | bcfg2-784f1580709eae996134923b9fd5f557202d59cb.tar.gz bcfg2-784f1580709eae996134923b9fd5f557202d59cb.tar.bz2 bcfg2-784f1580709eae996134923b9fd5f557202d59cb.zip |
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.
Diffstat (limited to 'src/lib/Bcfg2/Server/Plugins')
-rw-r--r-- | src/lib/Bcfg2/Server/Plugins/Packages/Layman.py | 133 | ||||
-rw-r--r-- | src/lib/Bcfg2/Server/Plugins/Packages/Portage.py | 8 |
2 files changed, 141 insertions, 0 deletions
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..947fa0319 --- /dev/null +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Layman.py @@ -0,0 +1,133 @@ +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, setup): + Bcfg2.Server.Plugin.Debuggable.__init__(self) + self.basepath = basepath + self.xsource = xsource + self.setup = setup + + 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 + self.essentialpkgs = set() + self.arches = [item.text for item in xsource.findall('Arch')] + + self.url_map = [dict(version=None, component=None, arch=arch, + url=self.url, baseurl=self.url) for arch in self.arches] + + #: A list of the the names of packages that are blacklisted + #: from this source + self.blacklist = [item.text for item in xsource.findall('Blacklist')] + + #: A list of the the names of packages that are whitelisted in + #: this source + self.whitelist = [item.text for item in xsource.findall('Whitelist')] + + + # configure layman + base = os.path.join(basepath, 'layman') + storage = os.path.join(base, 'overlays') + 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': [self.url] + }) + self.api = layman.LaymanAPI(config) + + # path + self.dir = os.path.join(storage, 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 get_repo_name(self, url_map): + return self.name + + 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.setup.cfp.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(self.name): + self.logger.error("Packages: Failed adding layman" + " overlay '%s'" % self.name) + return False + + if force_update: + if not self.api.sync(self.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 938ddad4d..ac074f879 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/' @@ -149,6 +150,13 @@ class PortageCollection(Collection): env = portage.settings.configdict['backupenv'] + # add layman overlays + env['PORTDIR_OVERLAY'] = '' + for overlay in self: + 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'], |