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): Bcfg2.Server.Plugin.Debuggable.__init__(self) self.basepath = basepath self.xsource = xsource 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 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): """ Return true if this source applies to the given client, i.e., the client is in all necessary groups. :param metadata: The client metadata to check to see if this source applies :type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata :returns: bool """ # check arch groups if not self.arch_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 def arch_groups_match(self, metadata): """ Returns True if the client is in an arch group that matches the arch of this source. :returns: bool """ for arch in self.arches: if arch in metadata.groups: return True return False