From 7d6032e82ea26baf82c64435925d6991d812e768 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Wed, 14 Jan 2015 23:35:22 +0100 Subject: Plugins/Packages: fix initialization of YumSource During __init__ of the parent class get_repo_name is called. That needs fields (pump_id) that are defined later in the __init__ of YumSource. We introduce the new function _init_attributes to parse all attributes out of the tag before calling any other functions. --- src/lib/Bcfg2/Server/Plugins/Packages/Source.py | 134 ++++++++++++++---------- 1 file changed, 77 insertions(+), 57 deletions(-) (limited to 'src/lib/Bcfg2/Server/Plugins/Packages/Source.py') diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Source.py b/src/lib/Bcfg2/Server/Plugins/Packages/Source.py index 30cdd543f..c09a9988b 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Source.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Source.py @@ -143,6 +143,83 @@ class Source(Bcfg2.Server.Plugin.Debuggable): # pylint: disable=R0902 #: source self.essentialpkgs = set() + self._init_attributes(basepath, xsource, setup) + + #: A set of all package names in this source. This will not + #: necessarily be populated, particularly by backends that + #: reimplement large portions of + #: :class:`Bcfg2.Server.Plugins.Packages.Collection.Collection` + self.pkgnames = set() + + #: A dict of ```` -> ````. + #: This will not necessarily be populated, particularly by + #: backends that reimplement large portions of + #: :class:`Bcfg2.Server.Plugins.Packages.Collection.Collection` + self.deps = dict() + + #: A dict of ```` -> ````. This will not necessarily be populated, + #: particularly by backends that reimplement large portions of + #: :class:`Bcfg2.Server.Plugins.Packages.Collection.Collection` + self.provides = dict() + + #: The file (or directory) used for this source's cache data + self.cachefile = os.path.join(self.basepath, + "cache-%s" % self.cachekey) + if not self.rawurl: + baseurl = self.url + "%(version)s/%(component)s/%(arch)s/" + else: + baseurl = self.rawurl + + #: A list of dicts, each of which describes the URL to one + #: repository contained in this source. Each dict contains + #: the following keys: + #: + #: * ``version``: The version of the repo (``None`` for + #: ``rawurl`` repos) + #: * ``component``: The component use to form this URL + #: (``None`` for ``rawurl`` repos) + #: * ``arch``: The architecture of this repo + #: * ``baseurl``: Either the ``rawurl`` attribute, or the + #: format string built from the ``url`` attribute + #: * ``url``: The actual URL to the repository + self.url_map = [] + for arch in self.arches: + if self.url: + usettings = [dict(version=self.version, component=comp, + arch=arch, debsrc=self.debsrc) + for comp in self.components] + else: # rawurl given + usettings = [dict(version=self.version, component=None, + arch=arch, debsrc=self.debsrc)] + + for setting in usettings: + if not self.rawurl: + setting['baseurl'] = self.url + else: + setting['baseurl'] = self.rawurl + setting['url'] = baseurl % setting + setting['name'] = self.get_repo_name(setting) + self.url_map.extend(usettings) + + def _init_attributes(self, basepath, xsource, setup): + """ + This functions evaluates the Source tag and parses all + attributes. Override this function in a sub class to + parse specific attributes. Do not use ``__init__`` because + ``Source.__init__`` may call other functions that already + need this specific fields. This functions is called before + any other function. + + :param basepath: The base filesystem path under which cache + data for this source should be stored + :type basepath: string + :param xsource: The XML tag that describes this source + :type source: lxml.etree._Element + :param setup: A Bcfg2 options dict + :type setup: dict + """ + #: A list of the text of all 'Component' attributes of this #: source from XML self.components = [item.text for item in xsource.findall('Component')] @@ -241,63 +318,6 @@ class Source(Bcfg2.Server.Plugin.Debuggable): # pylint: disable=R0902 self.conditions.append(lambda m, el=el: el.get("name") == m.hostname) - #: A set of all package names in this source. This will not - #: necessarily be populated, particularly by backends that - #: reimplement large portions of - #: :class:`Bcfg2.Server.Plugins.Packages.Collection.Collection` - self.pkgnames = set() - - #: A dict of ```` -> ````. - #: This will not necessarily be populated, particularly by - #: backends that reimplement large portions of - #: :class:`Bcfg2.Server.Plugins.Packages.Collection.Collection` - self.deps = dict() - - #: A dict of ```` -> ````. This will not necessarily be populated, - #: particularly by backends that reimplement large portions of - #: :class:`Bcfg2.Server.Plugins.Packages.Collection.Collection` - self.provides = dict() - - #: The file (or directory) used for this source's cache data - self.cachefile = os.path.join(self.basepath, - "cache-%s" % self.cachekey) - if not self.rawurl: - baseurl = self.url + "%(version)s/%(component)s/%(arch)s/" - else: - baseurl = self.rawurl - - #: A list of dicts, each of which describes the URL to one - #: repository contained in this source. Each dict contains - #: the following keys: - #: - #: * ``version``: The version of the repo (``None`` for - #: ``rawurl`` repos) - #: * ``component``: The component use to form this URL - #: (``None`` for ``rawurl`` repos) - #: * ``arch``: The architecture of this repo - #: * ``baseurl``: Either the ``rawurl`` attribute, or the - #: format string built from the ``url`` attribute - #: * ``url``: The actual URL to the repository - self.url_map = [] - for arch in self.arches: - if self.url: - usettings = [dict(version=self.version, component=comp, - arch=arch, debsrc=self.debsrc) - for comp in self.components] - else: # rawurl given - usettings = [dict(version=self.version, component=None, - arch=arch, debsrc=self.debsrc)] - - for setting in usettings: - if not self.rawurl: - setting['baseurl'] = self.url - else: - setting['baseurl'] = self.rawurl - setting['url'] = baseurl % setting - setting['name'] = self.get_repo_name(setting) - self.url_map.extend(usettings) - @property def cachekey(self): """ A unique key for this source that will be used to generate -- cgit v1.2.3-1-g7c22 From d2a52e47c867f8f5864781f200bed4d0adf373b3 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Fri, 23 Jan 2015 17:44:20 +0100 Subject: Plugins/Packages: all attributes should be defined in __init__ --- src/lib/Bcfg2/Server/Plugins/Packages/Source.py | 117 ++++++++++++++---------- 1 file changed, 69 insertions(+), 48 deletions(-) (limited to 'src/lib/Bcfg2/Server/Plugins/Packages/Source.py') diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Source.py b/src/lib/Bcfg2/Server/Plugins/Packages/Source.py index c09a9988b..cf26c982f 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Source.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Source.py @@ -143,6 +143,75 @@ class Source(Bcfg2.Server.Plugin.Debuggable): # pylint: disable=R0902 #: source self.essentialpkgs = set() + #: A list of the text of all 'Component' attributes of this + #: source from XML + self.components = [] + + #: A list of the arches supported by this source + self.arches = [] + + #: A list of the the names of packages that are blacklisted + #: from this source + self.blacklist = [] + + #: A list of the the names of packages that are whitelisted in + #: this source + self.whitelist = [] + + #: Whether or not to include deb-src lines in the generated APT + #: configuration + self.debsrc = False + + #: A dict of repository options that will be included in the + #: configuration generated on the server side (if such is + #: applicable; most backends do not generate any sort of + #: repository configuration on the Bcfg2 server) + self.server_options = dict() + + #: A dict of repository options that will be included in the + #: configuration generated for the client (if that is + #: supported by the backend) + self.client_options = dict() + + #: A list of URLs to GPG keys that apply to this source + self.gpgkeys = [] + + #: Whether or not to include essential packages from this source + self.essential = True + + #: Whether or not to include recommended packages from this source + self.recommended = False + + #: The "rawurl" attribute from :attr:`xsource`, if applicable. + #: A trailing slash is automatically appended to this if there + #: wasn't one already present. + self.rawurl = None + + #: The "url" attribute from :attr:`xsource`, if applicable. A + #: trailing slash is automatically appended to this if there + #: wasn't one already present. + self.url = None + + #: The "version" attribute from :attr:`xsource` + self.version = None + + #: The "name" attribute from :attr:`xsource` + self.name = None + + #: A list of predicates that are used to determine if this + #: source applies to a given + #: :class:`Bcfg2.Server.Plugins.Metadata.ClientMetadata` + #: object. + self.conditions = [] + + #: Formerly, :ref:`server-plugins-generators-packages` only + #: supported applying package sources to groups; that is, they + #: could not be assigned by more complicated logic like + #: per-client repositories and group or client negation. This + #: attribute attempts to provide for some limited backwards + #: compat with older code that relies on this. + self.groups = [] + self._init_attributes(basepath, xsource, setup) #: A set of all package names in this source. This will not @@ -220,35 +289,12 @@ class Source(Bcfg2.Server.Plugin.Debuggable): # pylint: disable=R0902 :type setup: dict """ - #: A list of the text of all 'Component' attributes of this - #: source from XML self.components = [item.text for item in xsource.findall('Component')] - - #: A list of the arches supported by this source self.arches = [item.text for item in xsource.findall('Arch')] - - #: 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')] - - #: Whether or not to include deb-src lines in the generated APT - #: configuration self.debsrc = xsource.get('debsrc', 'false') == 'true' - #: A dict of repository options that will be included in the - #: configuration generated on the server side (if such is - #: applicable; most backends do not generate any sort of - #: repository configuration on the Bcfg2 server) - self.server_options = dict() - - #: A dict of repository options that will be included in the - #: configuration generated for the client (if that is - #: supported by the backend) - self.client_options = dict() opts = xsource.findall("Options") for el in opts: repoopts = dict([(k, v) @@ -259,48 +305,23 @@ class Source(Bcfg2.Server.Plugin.Debuggable): # pylint: disable=R0902 if el.get("serveronly", "false").lower() == "false": self.client_options.update(repoopts) - #: A list of URLs to GPG keys that apply to this source self.gpgkeys = [el.text for el in xsource.findall("GPGKey")] - #: Whether or not to include essential packages from this source self.essential = xsource.get('essential', 'true').lower() == 'true' - - #: Whether or not to include recommended packages from this source self.recommended = xsource.get('recommended', 'false').lower() == 'true' - #: The "rawurl" attribute from :attr:`xsource`, if applicable. - #: A trailing slash is automatically appended to this if there - #: wasn't one already present. self.rawurl = xsource.get('rawurl', '') if self.rawurl and not self.rawurl.endswith("/"): self.rawurl += "/" - #: The "url" attribute from :attr:`xsource`, if applicable. A - #: trailing slash is automatically appended to this if there - #: wasn't one already present. self.url = xsource.get('url', '') if self.url and not self.url.endswith("/"): self.url += "/" - #: The "version" attribute from :attr:`xsource` self.version = xsource.get('version', '') - - #: The "name" attribute from :attr:`xsource` self.name = xsource.get('name', None) - #: A list of predicates that are used to determine if this - #: source applies to a given - #: :class:`Bcfg2.Server.Plugins.Metadata.ClientMetadata` - #: object. - self.conditions = [] - #: Formerly, :ref:`server-plugins-generators-packages` only - #: supported applying package sources to groups; that is, they - #: could not be assigned by more complicated logic like - #: per-client repositories and group or client negation. This - #: attribute attempts to provide for some limited backwards - #: compat with older code that relies on this. - self.groups = [] for el in xsource.iterancestors(): if el.tag == "Group": if el.get("negate", "false").lower() == "true": -- cgit v1.2.3-1-g7c22 From eafcb0ad931c5ae2d34e564c811a8c4cc0ee6278 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Fri, 23 Jan 2015 17:57:16 +0100 Subject: Plugins/Packages/Source: Remove unused arguments of _init_attributes --- src/lib/Bcfg2/Server/Plugins/Packages/Source.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'src/lib/Bcfg2/Server/Plugins/Packages/Source.py') diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Source.py b/src/lib/Bcfg2/Server/Plugins/Packages/Source.py index cf26c982f..6c5b61742 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Source.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Source.py @@ -212,7 +212,7 @@ class Source(Bcfg2.Server.Plugin.Debuggable): # pylint: disable=R0902 #: compat with older code that relies on this. self.groups = [] - self._init_attributes(basepath, xsource, setup) + self._init_attributes(xsource) #: A set of all package names in this source. This will not #: necessarily be populated, particularly by backends that @@ -271,7 +271,7 @@ class Source(Bcfg2.Server.Plugin.Debuggable): # pylint: disable=R0902 setting['name'] = self.get_repo_name(setting) self.url_map.extend(usettings) - def _init_attributes(self, basepath, xsource, setup): + def _init_attributes(self, xsource): """ This functions evaluates the Source tag and parses all attributes. Override this function in a sub class to @@ -280,13 +280,8 @@ class Source(Bcfg2.Server.Plugin.Debuggable): # pylint: disable=R0902 need this specific fields. This functions is called before any other function. - :param basepath: The base filesystem path under which cache - data for this source should be stored - :type basepath: string :param xsource: The XML tag that describes this source :type source: lxml.etree._Element - :param setup: A Bcfg2 options dict - :type setup: dict """ self.components = [item.text for item in xsource.findall('Component')] -- cgit v1.2.3-1-g7c22 From 3829eda6e46a291875d989ecb0afa6a28ed0e3b8 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Wed, 25 Mar 2015 20:23:18 +0100 Subject: Server/Plugins/Packages: Fix _init_attributes position. _init_attributes should be called after all properties of the Source class are initialized (so that _init_attributes could overwrite some of it). The Yum class initializes self.deps with a different default entry, that should not be reset by __init__ of Source afterwards. --- src/lib/Bcfg2/Server/Plugins/Packages/Source.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/lib/Bcfg2/Server/Plugins/Packages/Source.py') diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Source.py b/src/lib/Bcfg2/Server/Plugins/Packages/Source.py index 6c5b61742..7aa688f12 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Source.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Source.py @@ -212,8 +212,6 @@ class Source(Bcfg2.Server.Plugin.Debuggable): # pylint: disable=R0902 #: compat with older code that relies on this. self.groups = [] - self._init_attributes(xsource) - #: A set of all package names in this source. This will not #: necessarily be populated, particularly by backends that #: reimplement large portions of @@ -232,6 +230,8 @@ class Source(Bcfg2.Server.Plugin.Debuggable): # pylint: disable=R0902 #: :class:`Bcfg2.Server.Plugins.Packages.Collection.Collection` self.provides = dict() + self._init_attributes(xsource) + #: The file (or directory) used for this source's cache data self.cachefile = os.path.join(self.basepath, "cache-%s" % self.cachekey) -- cgit v1.2.3-1-g7c22