summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Sulfrian <alexander@sulfrian.net>2013-03-12 03:30:04 +0100
committerAlexander Sulfrian <alexander@sulfrian.net>2014-02-26 13:38:17 +0100
commit784f1580709eae996134923b9fd5f557202d59cb (patch)
treeb6946cfe651d858d5479598c06e4c94db277d632
parent9e5645f95fe5deedae084f371509888e514e19b0 (diff)
downloadbcfg2-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.
-rw-r--r--schemas/packages.xsd1
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Packages/Layman.py133
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Packages/Portage.py8
3 files changed, 142 insertions, 0 deletions
diff --git a/schemas/packages.xsd b/schemas/packages.xsd
index 7819a1ba0..e4724fabe 100644
--- a/schemas/packages.xsd
+++ b/schemas/packages.xsd
@@ -15,6 +15,7 @@
<xsd:enumeration value="apt"/>
<xsd:enumeration value="pac"/>
<xsd:enumeration value="portage"/>
+ <xsd:enumeration value="layman"/>
</xsd:restriction>
</xsd:simpleType>
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'],