From 0da4208c47162f7e48d98888b2256be378c86030 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Tue, 4 Nov 2014 11:32:19 -0600 Subject: Yum.py: Fix traceback when arch missing Sometimes repositories may not contain packages for a specific architecture group. This handles that case gracefully instead of causing a traceback and failing to bind all Package entries. Signed-off-by: Sol Jerome --- src/lib/Bcfg2/Server/Plugins/Packages/Yum.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py index 6139a28b5..4ee9cce52 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py @@ -1287,10 +1287,13 @@ class YumSource(Source): arch = [a for a in self.arches if a in metadata.groups] if not arch: return False - return ((package in self.packages['global'] or - package in self.packages[arch[0]]) and - package not in self.blacklist and - (len(self.whitelist) == 0 or package in self.whitelist)) + try: + return ((package in self.packages['global'] or + package in self.packages[arch[0]]) and + package not in self.blacklist and + (len(self.whitelist) == 0 or package in self.whitelist)) + except KeyError: + return False is_package.__doc__ = Source.is_package.__doc__ def get_vpkgs(self, metadata): -- cgit v1.2.3-1-g7c22 From c4a4af8d9cbcd9bcb398fcbdac4e724b7c416332 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Thu, 13 Nov 2014 13:17:38 -0600 Subject: doc: Fix typo Signed-off-by: Sol Jerome --- doc/appendix/guides/authentication.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/appendix/guides/authentication.txt b/doc/appendix/guides/authentication.txt index b8ec82590..1af061170 100644 --- a/doc/appendix/guides/authentication.txt +++ b/doc/appendix/guides/authentication.txt @@ -146,7 +146,7 @@ Allowed values are: +-------------------+------------------------------------------+ ``cert+password`` is the default. This can be changed by setting the -``authentication`` parameter in the ``[communcation]`` section of +``authentication`` parameter in the ``[communication]`` section of ``bcfg2.conf``. For instance, to set ``bootstrap`` mode as the global default, you would add the following to ``bcfg2.conf``:: -- cgit v1.2.3-1-g7c22 From 24cf0cea4cfe34c18dcb53af074149237386fa33 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Wed, 17 Dec 2014 15:03:20 -0600 Subject: schemas/clients.xsd: Fix typo Signed-off-by: Sol Jerome --- schemas/clients.xsd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schemas/clients.xsd b/schemas/clients.xsd index 20a77b0dd..b6d04b3bf 100644 --- a/schemas/clients.xsd +++ b/schemas/clients.xsd @@ -60,7 +60,7 @@ - Profile group naem to associate this client with. + Profile group name to associate this client with. -- cgit v1.2.3-1-g7c22 From 9e91535a45291ea67bc43966c8ec7befebcee739 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Fri, 2 Jan 2015 08:42:05 -0600 Subject: doc: Remove obsolete feature See the Obsoleted Features section at http://nagios.sourceforge.net/docs/nagioscore/4/en/whatsnew.html Signed-off-by: Sol Jerome --- doc/server/plugins/generators/nagiosgen.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/server/plugins/generators/nagiosgen.txt b/doc/server/plugins/generators/nagiosgen.txt index 0ae922fa3..2cbc9fb5e 100644 --- a/doc/server/plugins/generators/nagiosgen.txt +++ b/doc/server/plugins/generators/nagiosgen.txt @@ -29,7 +29,6 @@ Create default host, and group specs in: check_period 24x7 contact_groups admins event_handler_enabled 1 - failure_prediction_enabled 1 flap_detection_enabled 1 initial_state o max_check_attempts 10 -- cgit v1.2.3-1-g7c22 From 2685205240144a6b95bba5062e5fcd374a82edfe Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Fri, 16 Jan 2015 01:31:14 +0100 Subject: testsuite/requirements: python-daemon >= 2.0.0 is broken --- testsuite/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testsuite/requirements.txt b/testsuite/requirements.txt index 898249389..48657acf7 100644 --- a/testsuite/requirements.txt +++ b/testsuite/requirements.txt @@ -4,4 +4,4 @@ mock sphinx pylint<1.0 pep8 -python-daemon +python-daemon<2.0.0 -- cgit v1.2.3-1-g7c22 From 4609569ec9a7b9ea083c5546fa38ef401bba5fa8 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Fri, 16 Jan 2015 02:58:40 +0100 Subject: testsuite: support for python-2.7.9 pylint could not parse the dynamic assignment of the PROTOCOL_* values in the ssl module (the real values are in the _ssl extension). We dynamically add here the PROTOCOL_* constants we need. --- testsuite/ext/ssl_protocols.py | 17 +++++++++++++++++ testsuite/pylintrc.conf | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 testsuite/ext/ssl_protocols.py diff --git a/testsuite/ext/ssl_protocols.py b/testsuite/ext/ssl_protocols.py new file mode 100644 index 000000000..66068d2a9 --- /dev/null +++ b/testsuite/ext/ssl_protocols.py @@ -0,0 +1,17 @@ +try: + from logilab.astng import MANAGER, scoped_nodes, node_classes + PYLINT=0 +except ImportError: + from astroid import MANAGER, scoped_nodes, node_classes + PYLINT=1 + +def ssl_transform(module): + if module.name == 'ssl': + for proto in ('SSLv23', 'TLSv1'): + module.locals['PROTOCOL_%s' % proto] = [node_classes.Const()] + +def register(linter): + if PYLINT == 0: + MANAGER.register_transformer(ssl_transform) + else: + MANAGER.register_transform(scoped_nodes.Module, ssl_transform) diff --git a/testsuite/pylintrc.conf b/testsuite/pylintrc.conf index 94904877b..b3340cb4f 100644 --- a/testsuite/pylintrc.conf +++ b/testsuite/pylintrc.conf @@ -19,7 +19,7 @@ persistent=no # List of plugins (as comma separated values of python modules names) to load, # usually to register additional checkers. -load-plugins=ext.exception_messages +load-plugins=ext.exception_messages,ext.ssl_protocols [MESSAGES CONTROL] -- cgit v1.2.3-1-g7c22 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 ++++++++++++++---------- src/lib/Bcfg2/Server/Plugins/Packages/Yum.py | 7 +- 2 files changed, 81 insertions(+), 60 deletions(-) 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 diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py index 6139a28b5..ae8ac5d6f 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py @@ -1028,8 +1028,9 @@ class YumSource(Source): #: YumSource sets the ``type`` on Package entries to "yum" ptype = 'yum' - def __init__(self, basepath, xsource, setup): - Source.__init__(self, basepath, xsource, setup) + def _init_attributes(self, basepath, xsource, setup): + Source._init_attributes(self, basepath, xsource, setup) + self.pulp_id = None if HAS_PULP and xsource.get("pulp_id"): self.pulp_id = xsource.get("pulp_id") @@ -1071,7 +1072,7 @@ class YumSource(Source): self.needed_paths = set() self.file_to_arch = dict() self.yumgroups = dict() - __init__.__doc__ = Source.__init__.__doc__ + _init_attributes.__doc__ = Source._init_attributes.__doc__ @property def use_yum(self): -- 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 ++++++++++++++---------- src/lib/Bcfg2/Server/Plugins/Packages/Yum.py | 17 +++- 2 files changed, 81 insertions(+), 53 deletions(-) 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": diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py index ae8ac5d6f..6669d3066 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py @@ -1028,10 +1028,21 @@ class YumSource(Source): #: YumSource sets the ``type`` on Package entries to "yum" ptype = 'yum' + def __init__(self, basepath, xsource, setup): + self.filemap = dict() + self.file_to_arch = dict() + self.needed_paths = set() + self.packages = dict() + self.yumgroups = dict() + self.pulp_id = None + self.repo = None + + Source.__init__(self, basepath, xsource, setup) + __init__.__doc__ = Source.__init__.__doc__ + def _init_attributes(self, basepath, xsource, setup): Source._init_attributes(self, basepath, xsource, setup) - self.pulp_id = None if HAS_PULP and xsource.get("pulp_id"): self.pulp_id = xsource.get("pulp_id") @@ -1064,14 +1075,10 @@ class YumSource(Source): self.repo['relative_path']) self.arches = [self.repo['arch']] - self.packages = dict() self.deps = dict([('global', dict())]) self.provides = dict([('global', dict())]) self.filemap = dict([(x, dict()) for x in ['global'] + self.arches]) - self.needed_paths = set() - self.file_to_arch = dict() - self.yumgroups = dict() _init_attributes.__doc__ = Source._init_attributes.__doc__ @property -- 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 ++------- src/lib/Bcfg2/Server/Plugins/Packages/Yum.py | 4 ++-- 2 files changed, 4 insertions(+), 9 deletions(-) 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')] diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py index 6669d3066..20b0e103d 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py @@ -1040,8 +1040,8 @@ class YumSource(Source): Source.__init__(self, basepath, xsource, setup) __init__.__doc__ = Source.__init__.__doc__ - def _init_attributes(self, basepath, xsource, setup): - Source._init_attributes(self, basepath, xsource, setup) + def _init_attributes(self, xsource): + Source._init_attributes(self, xsource) if HAS_PULP and xsource.get("pulp_id"): self.pulp_id = xsource.get("pulp_id") -- cgit v1.2.3-1-g7c22 From 78cac1d0a6923ebc73ff221f8501885c36c112c1 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Tue, 27 Jan 2015 05:46:13 +0100 Subject: Make SSHbase also a Connector plugin. Make the public host key data avaialabe for the templates. --- src/lib/Bcfg2/Server/Plugins/SSHbase.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/lib/Bcfg2/Server/Plugins/SSHbase.py b/src/lib/Bcfg2/Server/Plugins/SSHbase.py index 2deea5f07..0152fcf70 100644 --- a/src/lib/Bcfg2/Server/Plugins/SSHbase.py +++ b/src/lib/Bcfg2/Server/Plugins/SSHbase.py @@ -93,6 +93,7 @@ class KnownHostsEntrySet(Bcfg2.Server.Plugin.EntrySet): class SSHbase(Bcfg2.Server.Plugin.Plugin, Bcfg2.Server.Plugin.Caching, + Bcfg2.Server.Plugin.Connector, Bcfg2.Server.Plugin.Generator, Bcfg2.Server.Plugin.PullTarget): """ @@ -127,6 +128,7 @@ class SSHbase(Bcfg2.Server.Plugin.Plugin, def __init__(self, core, datastore): Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore) Bcfg2.Server.Plugin.Caching.__init__(self) + Bcfg2.Server.Plugin.Connector.__init__(self) Bcfg2.Server.Plugin.Generator.__init__(self) Bcfg2.Server.Plugin.PullTarget.__init__(self) self.ipcache = {} @@ -444,3 +446,15 @@ class SSHbase(Bcfg2.Server.Plugin.Plugin, self.logger.error("Failed to pull %s. This file does not " "currently exist on the client" % entry.get('name')) + + def get_additional_data(self, metadata): + data = dict() + for key in self.keypatterns: + if key.endswith(".pub"): + try: + keyfile = "/etc/ssh/" + key + entry = self.entries[keyfile].best_matching(metadata) + data[key] = entry.data + except Bcfg2.Server.Plugin.PluginExecutionError: + pass + return data -- cgit v1.2.3-1-g7c22 From deb8729a09d74d2efe5bdf86e3a2d3c1274590ab Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Tue, 24 Feb 2015 18:05:13 +0100 Subject: Server/Plugins/Metadata: Reject passwd clients, if auth_type is cert If the auth type (either globally or specific for the client) is set to cert auth, we have to reject clients that does not provide a cert. --- doc/releases/1.3.6.txt | 2 ++ src/lib/Bcfg2/Server/Plugins/Metadata.py | 9 +++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/doc/releases/1.3.6.txt b/doc/releases/1.3.6.txt index 757fbf6f5..f41320f1a 100644 --- a/doc/releases/1.3.6.txt +++ b/doc/releases/1.3.6.txt @@ -30,5 +30,7 @@ This is primarily a bugfix release. https://docs.djangoproject.com/en/1.7/ref/settings/#std:setting-OPTIONS +* Authentication: Reject passwd auth, if authentication is set to "cert" + Special thanks to the following contributors for this release: Michael Fenn, Matt Kemp, Alexander Sulfrian, Jonathan Billings. diff --git a/src/lib/Bcfg2/Server/Plugins/Metadata.py b/src/lib/Bcfg2/Server/Plugins/Metadata.py index 1e5544c6b..f805772a7 100644 --- a/src/lib/Bcfg2/Server/Plugins/Metadata.py +++ b/src/lib/Bcfg2/Server/Plugins/Metadata.py @@ -1391,8 +1391,6 @@ class Metadata(Bcfg2.Server.Plugin.Metadata, # look at cert.cN client = certinfo['commonName'] self.debug_log("Got cN %s; using as client name" % client) - auth_type = self.auth.get(client, - self.core.setup['authentication']) elif user == 'root': id_method = 'address' try: @@ -1414,6 +1412,13 @@ class Metadata(Bcfg2.Server.Plugin.Metadata, # we have the client name self.debug_log("Authenticating client %s" % client) + # validate id_method + auth_type = self.auth.get(client, self.core.setup['authentication']) + if auth_type == 'cert' and id_method != 'cert': + self.logger.error("Client %s does not provide a cert, but only " + "cert auth is allowed" % client) + return False + # next we validate the address if (id_method != 'uuid' and not self.validate_client_address(client, address)): -- cgit v1.2.3-1-g7c22 From cae39b746051ff5f3257342d0659340283b2d6ef Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Tue, 24 Feb 2015 16:29:07 -0600 Subject: Fix pylint errors This also pins pylint to <= 0.28 so we don't have to keep playing whack-a-mole with it. Also removes unnecessary suppression of apt warnings. This is no longer necessary in 12.04, so should be safe to remove. If you're on Ubuntu < 12.04, upgrade for heaven's sake. --- src/lib/Bcfg2/Client/Tools/APT.py | 30 +++++++++++++-------------- src/lib/Bcfg2/Client/Tools/MacPorts.py | 7 +++---- src/lib/Bcfg2/Client/Tools/POSIXUsers.py | 4 ++-- src/lib/Bcfg2/Client/Tools/YUM.py | 4 ++-- src/lib/Bcfg2/Client/Tools/__init__.py | 12 +++++------ src/lib/Bcfg2/Server/FileMonitor/__init__.py | 7 +++++-- src/lib/Bcfg2/Server/Lint/Validate.py | 25 ++++++++++------------ src/lib/Bcfg2/Server/Lint/ValidateJSON.py | 21 +++++++------------ src/lib/Bcfg2/Server/Lint/__init__.py | 12 +++++++++++ src/lib/Bcfg2/Server/Plugin/__init__.py | 5 ----- src/lib/Bcfg2/Server/Plugins/GroupPatterns.py | 10 ++++----- src/lib/Bcfg2/Server/Plugins/SSLCA.py | 23 ++++++++++---------- src/sbin/bcfg2-test | 5 ++++- testsuite/requirements.txt | 2 +- 14 files changed, 84 insertions(+), 83 deletions(-) diff --git a/src/lib/Bcfg2/Client/Tools/APT.py b/src/lib/Bcfg2/Client/Tools/APT.py index 300c9bc51..3c511681f 100644 --- a/src/lib/Bcfg2/Client/Tools/APT.py +++ b/src/lib/Bcfg2/Client/Tools/APT.py @@ -1,12 +1,10 @@ """This is the Bcfg2 support for apt-get.""" -# suppress apt API warnings -import warnings -warnings.filterwarnings("ignore", "apt API not stable yet", - FutureWarning) -import apt.cache import os import sys + +import apt.cache + import Bcfg2.Client.Tools @@ -47,20 +45,20 @@ class APT(Bcfg2.Client.Tools.Tool): for entry in struct if entry.tag == 'Path' and entry.get('type') == 'ignore'] - self.__important__ = self.__important__ + \ - ["%s/cache/debconf/config.dat" % self.var_path, - "%s/cache/debconf/templates.dat" % self.var_path, - '/etc/passwd', '/etc/group', - '%s/apt/apt.conf' % self.etc_path, - '%s/dpkg/dpkg.cfg' % self.etc_path] + \ + self.__important__ = self.__important__ + [ + "%s/cache/debconf/config.dat" % self.var_path, + "%s/cache/debconf/templates.dat" % self.var_path, + '/etc/passwd', '/etc/group', + '%s/apt/apt.conf' % self.etc_path, + '%s/dpkg/dpkg.cfg' % self.etc_path] + \ [entry.get('name') for struct in config for entry in struct - if entry.tag == 'Path' and - entry.get('name').startswith( - '%s/apt/sources.list' % self.etc_path)] + if (entry.tag == 'Path' and + entry.get('name').startswith( + '%s/apt/sources.list' % self.etc_path)] self.nonexistent = [entry.get('name') for struct in config for entry in struct - if entry.tag == 'Path' and - entry.get('type') == 'nonexistent'] + if (entry.tag == 'Path' and + entry.get('type') == 'nonexistent')] os.environ["DEBIAN_FRONTEND"] = 'noninteractive' self.actions = {} if self.setup['kevlar'] and not self.setup['dryrun']: diff --git a/src/lib/Bcfg2/Client/Tools/MacPorts.py b/src/lib/Bcfg2/Client/Tools/MacPorts.py index 40d90eec9..116b24687 100644 --- a/src/lib/Bcfg2/Client/Tools/MacPorts.py +++ b/src/lib/Bcfg2/Client/Tools/MacPorts.py @@ -42,10 +42,9 @@ class MacPorts(Bcfg2.Client.Tools.PkgTool): return False if entry.attrib['name'] in self.installed: - if (self.installed[entry.attrib['name']] == entry.attrib['version'] - or entry.attrib['version'] == 'any'): - # if (not self.setup['quick'] and - # entry.get('verify', 'true') == 'true'): + if (entry.attrib['version'] == 'any' or + self.installed[entry.attrib['name']] == + entry.attrib['version']): # FIXME: We should be able to check this once # http://trac.macports.org/ticket/15709 is implemented return True diff --git a/src/lib/Bcfg2/Client/Tools/POSIXUsers.py b/src/lib/Bcfg2/Client/Tools/POSIXUsers.py index bbae7abcc..b8451d9d6 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIXUsers.py +++ b/src/lib/Bcfg2/Client/Tools/POSIXUsers.py @@ -146,8 +146,8 @@ class POSIXUsers(Bcfg2.Client.Tools.Tool): """ Get a list of supplmentary groups that the user in the given entry is a member of """ return [g for g in self.existing['POSIXGroup'].values() - if entry.get("name") in g[3] - and self._in_managed_range('POSIXGroup', g[2])] + if entry.get("name") in g[3] and + self._in_managed_range('POSIXGroup', g[2])] def VerifyPOSIXUser(self, entry, _): """ Verify a POSIXUser entry """ diff --git a/src/lib/Bcfg2/Client/Tools/YUM.py b/src/lib/Bcfg2/Client/Tools/YUM.py index a584fec86..d1fcb0f4a 100644 --- a/src/lib/Bcfg2/Client/Tools/YUM.py +++ b/src/lib/Bcfg2/Client/Tools/YUM.py @@ -590,8 +590,8 @@ class YUM(Bcfg2.Client.Tools.PkgTool): "an RPM release") continue pkg_objs = [p for p in all_pkg_objs - if (p.version == nevra['version'] - and p.release == nevra['release'])] + if (p.version == nevra['version'] and + p.release == nevra['release'])] else: pkg_objs = self.yumbase.rpmdb.searchNevra(**short_yname(nevra)) if len(pkg_objs) == 0: diff --git a/src/lib/Bcfg2/Client/Tools/__init__.py b/src/lib/Bcfg2/Client/Tools/__init__.py index 0bec71e20..b5bfdb5de 100644 --- a/src/lib/Bcfg2/Client/Tools/__init__.py +++ b/src/lib/Bcfg2/Client/Tools/__init__.py @@ -471,9 +471,9 @@ class PkgTool(Tool): # set all package states to true and flush workqueues pkgnames = [pkg.get('name') for pkg in packages] for entry in list(states.keys()): - if (entry.tag == 'Package' - and entry.get('type') == self.pkgtype - and entry.get('name') in pkgnames): + if (entry.tag == 'Package' and + entry.get('type') == self.pkgtype and + entry.get('name') in pkgnames): self.logger.debug('Setting state to true for pkg %s' % entry.get('name')) states[entry] = True @@ -575,7 +575,7 @@ class SvcTool(Tool): return self.cmd.run(self.get_svc_command(service, 'stop')) def restart_service(self, service): - """ Restart a service. + """Restart a service. :param service: The service entry to modify :type service: lxml.etree._Element @@ -608,8 +608,8 @@ class SvcTool(Tool): return for entry in bundle: - if (not self.handlesEntry(entry) - or not self._install_allowed(entry)): + if (not self.handlesEntry(entry) or + not self._install_allowed(entry)): continue estatus = entry.get('status') diff --git a/src/lib/Bcfg2/Server/FileMonitor/__init__.py b/src/lib/Bcfg2/Server/FileMonitor/__init__.py index 7a5d901fd..083e50fe6 100644 --- a/src/lib/Bcfg2/Server/FileMonitor/__init__.py +++ b/src/lib/Bcfg2/Server/FileMonitor/__init__.py @@ -336,8 +336,11 @@ class FileMonitor(Debuggable): available = dict() # pylint: disable=C0103 # TODO: loading the monitor drivers should be automatic -from Bcfg2.Server.FileMonitor.Pseudo import Pseudo -available['pseudo'] = Pseudo +try: + from Bcfg2.Server.FileMonitor.Pseudo import Pseudo + available['pseudo'] = Pseudo +except ImportError: + pass try: from Bcfg2.Server.FileMonitor.Fam import Fam diff --git a/src/lib/Bcfg2/Server/Lint/Validate.py b/src/lib/Bcfg2/Server/Lint/Validate.py index 3efcc890d..1e33ec398 100644 --- a/src/lib/Bcfg2/Server/Lint/Validate.py +++ b/src/lib/Bcfg2/Server/Lint/Validate.py @@ -1,12 +1,16 @@ -""" Ensure that all XML files in the Bcfg2 repository validate -according to their respective schemas. """ +"""Validate XML files. +Ensure that all XML files in the Bcfg2 repository validate according +to their respective schemas. +""" + +import glob import os import sys -import glob -import fnmatch + import lxml.etree from subprocess import Popen, PIPE, STDOUT + import Bcfg2.Server.Lint @@ -204,17 +208,10 @@ class Validate(Bcfg2.Server.Lint.ServerlessPlugin): values are lists of the full paths to all files in the Bcfg2 repository (or given with ``bcfg2-lint --stdin``) that match the glob.""" - if self.files is not None: - listfiles = lambda p: fnmatch.filter(self.files, - os.path.join('*', p)) - else: - listfiles = lambda p: glob.glob(os.path.join(self.config['repo'], - p)) - for path in self.filesets.keys(): if '/**/' in path: if self.files is not None: - self.filelists[path] = listfiles(path) + self.filelists[path] = self.list_matching_files(path) else: # self.files is None fpath, fname = path.split('/**/') self.filelists[path] = [] @@ -225,9 +222,9 @@ class Validate(Bcfg2.Server.Lint.ServerlessPlugin): for f in files if f == fname]) else: - self.filelists[path] = listfiles(path) + self.filelists[path] = self.list_matching_files(path) - self.filelists['props'] = listfiles("Properties/*.xml") + self.filelists['props'] = self.list_matching_files("Properties/*.xml") def _load_schema(self, filename): """ Load an XML schema document, returning the Schema object diff --git a/src/lib/Bcfg2/Server/Lint/ValidateJSON.py b/src/lib/Bcfg2/Server/Lint/ValidateJSON.py index 1f55962eb..bdbe6a271 100644 --- a/src/lib/Bcfg2/Server/Lint/ValidateJSON.py +++ b/src/lib/Bcfg2/Server/Lint/ValidateJSON.py @@ -1,11 +1,13 @@ -"""Ensure that all JSON files in the Bcfg2 repository are +"""Validate JSON files. + +Ensure that all JSON files in the Bcfg2 repository are valid. Currently, the only plugins that uses JSON are Ohai and -Properties.""" +Properties. +""" import os import sys -import glob -import fnmatch + import Bcfg2.Server.Lint try: @@ -48,18 +50,11 @@ class ValidateJSON(Bcfg2.Server.Lint.ServerlessPlugin): def get_files(self): """Return a list of all JSON files to validate, based on :attr:`Bcfg2.Server.Lint.ValidateJSON.ValidateJSON.globs`. """ - if self.files is not None: - listfiles = lambda p: fnmatch.filter(self.files, - os.path.join('*', p)) - else: - listfiles = lambda p: glob.glob(os.path.join(self.config['repo'], - p)) - rv = [] for path in self.globs: if '/**/' in path: if self.files is not None: - rv.extend(listfiles(path)) + rv.extend(self.list_matching_files(path)) else: # self.files is None fpath, fname = path.split('/**/') for root, _, files in \ @@ -68,5 +63,5 @@ class ValidateJSON(Bcfg2.Server.Lint.ServerlessPlugin): rv.extend([os.path.join(root, f) for f in files if f == fname]) else: - rv.extend(listfiles(path)) + rv.extend(self.list_matching_files(path)) return rv diff --git a/src/lib/Bcfg2/Server/Lint/__init__.py b/src/lib/Bcfg2/Server/Lint/__init__.py index 28644263f..ae2b81a61 100644 --- a/src/lib/Bcfg2/Server/Lint/__init__.py +++ b/src/lib/Bcfg2/Server/Lint/__init__.py @@ -1,14 +1,19 @@ """ Base classes for Lint plugins and error handling """ import os +import fnmatch +import glob import sys import logging from copy import copy import textwrap +import time + import lxml.etree import fcntl import termios import struct + from Bcfg2.Compat import walk_packages plugins = [m[1] for m in walk_packages(path=__path__)] # pylint: disable=C0103 @@ -139,6 +144,13 @@ class Plugin(object): xml_declaration=False).decode("UTF-8").strip() return " line %s: %s" % (element.sourceline, xml) + def list_matching_files(self, path): + """list all files matching the path in self.files or the bcfg2 repo.""" + if self.files is not None: + return fnmatch.filter(self.files, os.path.join('*', path)) + else: + return glob.glob(os.path.join(self.config['repo'], path)) + class ErrorHandler(object): """ A class to handle errors for bcfg2-lint plugins """ diff --git a/src/lib/Bcfg2/Server/Plugin/__init__.py b/src/lib/Bcfg2/Server/Plugin/__init__.py index ed1282ba0..05bb92223 100644 --- a/src/lib/Bcfg2/Server/Plugin/__init__.py +++ b/src/lib/Bcfg2/Server/Plugin/__init__.py @@ -11,11 +11,6 @@ documentation it's not necessary to use the submodules. E.g., you can from Bcfg2.Server.Plugin.base import Plugin """ - -import os -import sys -sys.path.append(os.path.dirname(__file__)) - # pylint: disable=W0401 from Bcfg2.Server.Plugin.base import * from Bcfg2.Server.Plugin.interfaces import * diff --git a/src/lib/Bcfg2/Server/Plugins/GroupPatterns.py b/src/lib/Bcfg2/Server/Plugins/GroupPatterns.py index 09685d972..eadd918b7 100644 --- a/src/lib/Bcfg2/Server/Plugins/GroupPatterns.py +++ b/src/lib/Bcfg2/Server/Plugins/GroupPatterns.py @@ -149,15 +149,13 @@ class GroupPatternsLint(Bcfg2.Server.Lint.ServerPlugin): def check(self, entry, groups, ptype="NamePattern"): """ Check a single pattern for validity """ - if ptype == "NamePattern": - pmap = lambda p: PatternMap(p, None, groups) - else: - pmap = lambda p: PatternMap(None, p, groups) - for el in entry.findall(ptype): pat = el.text try: - pmap(pat) + if ptype == "NamePattern": + PatternMap(pat, None, groups) + else: + PatternMap(None, pat, groups) except: # pylint: disable=W0702 err = sys.exc_info()[1] self.LintError("pattern-fails-to-initialize", diff --git a/src/lib/Bcfg2/Server/Plugins/SSLCA.py b/src/lib/Bcfg2/Server/Plugins/SSLCA.py index f111ffc60..a33b2f448 100644 --- a/src/lib/Bcfg2/Server/Plugins/SSLCA.py +++ b/src/lib/Bcfg2/Server/Plugins/SSLCA.py @@ -150,15 +150,13 @@ class SSLCAEntrySet(Bcfg2.Server.Plugin.EntrySet): if passphrase: cmd.extend(["-passin", "pass:%s" % passphrase]) - def _scrub_pass(arg): - """ helper to scrub the passphrase from the - argument list """ - if arg.startswith("pass:"): - return "pass:******" - else: - return arg - else: - _scrub_pass = lambda a: a + def _scrub_pass(arg): + """ helper to scrub the passphrase from the + argument list for debugging. """ + if arg.startswith("pass:"): + return "pass:******" + else: + return arg self.debug_log("SSLCA: Generating new certificate: %s" % " ".join(_scrub_pass(a) for a in cmd)) @@ -362,10 +360,13 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): """ The SSLCA generator handles the creation and management of ssl certificates and their keys. """ __author__ = 'g.hagger@gmail.com' - # python 2.5 doesn't support mixing *magic and keyword arguments - es_cls = lambda self, *args: SSLCAEntrySet(*args, **dict(parent=self)) es_child_cls = SSLCADataFile + def es_cls(self, *args): + """Fake entry set 'class' that sets this as the parent.""" + # python 2.5 doesn't support mixing *magic and keyword arguments + return SSLCAEntrySet(*args, **dict(parent=self)) + def get_ca(self, name): """ get a dict describing a CA from the config file """ return dict(self.core.setup.cfp.items("sslca_%s" % name)) diff --git a/src/sbin/bcfg2-test b/src/sbin/bcfg2-test index 7c38a65d8..1d89210c9 100755 --- a/src/sbin/bcfg2-test +++ b/src/sbin/bcfg2-test @@ -20,7 +20,10 @@ try: HAS_MULTIPROC = True except ImportError: HAS_MULTIPROC = False - active_children = lambda: [] # pylint: disable=C0103 + + def active_children(): + """active_children() when multiprocessing lib is missing.""" + return [] class CapturingLogger(object): diff --git a/testsuite/requirements.txt b/testsuite/requirements.txt index 48657acf7..0dd460b87 100644 --- a/testsuite/requirements.txt +++ b/testsuite/requirements.txt @@ -2,6 +2,6 @@ lxml nose mock sphinx -pylint<1.0 +pylint<0.29 pep8 python-daemon<2.0.0 -- cgit v1.2.3-1-g7c22 From f69d2c18d1351d49f4c1ffd2a6c282df0fa3d8e3 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Fri, 16 Jan 2015 03:53:00 +0100 Subject: Server/Core: drop privileges even if not running as daemon --- src/lib/Bcfg2/Options.py | 4 +++- src/lib/Bcfg2/Server/CherryPyCore.py | 16 ++++++++++------ src/lib/Bcfg2/Server/Core.py | 17 ++++++++++++++++- src/lib/Bcfg2/Server/MultiprocessingCore.py | 3 +++ src/sbin/bcfg2-info | 2 ++ 5 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/lib/Bcfg2/Options.py b/src/lib/Bcfg2/Options.py index 652e216a5..fdc34eb95 100644 --- a/src/lib/Bcfg2/Options.py +++ b/src/lib/Bcfg2/Options.py @@ -1348,7 +1348,9 @@ TEST_COMMON_OPTIONS = dict(noseopts=TEST_NOSEOPTS, validate=CFG_VALIDATION) INFO_COMMON_OPTIONS = dict(ppath=PARANOID_PATH, - max_copies=PARANOID_MAX_COPIES) + max_copies=PARANOID_MAX_COPIES, + daemon_uid=SERVER_DAEMON_USER, + daemon_gid=SERVER_DAEMON_GROUP) INFO_COMMON_OPTIONS.update(CLI_COMMON_OPTIONS) INFO_COMMON_OPTIONS.update(SERVER_COMMON_OPTIONS) diff --git a/src/lib/Bcfg2/Server/CherryPyCore.py b/src/lib/Bcfg2/Server/CherryPyCore.py index d097fd08f..c1581679c 100644 --- a/src/lib/Bcfg2/Server/CherryPyCore.py +++ b/src/lib/Bcfg2/Server/CherryPyCore.py @@ -103,17 +103,21 @@ class Core(BaseCore): return cherrypy.serving.response.body def _daemonize(self): - """ Drop privileges with - :class:`cherrypy.process.plugins.DropPrivileges`, daemonize - with :class:`cherrypy.process.plugins.Daemonizer`, and write a + """ Drop privileges, daemonize + with :class:`cherrypy.process.plugins.Daemonizer` and write a PID file with :class:`cherrypy.process.plugins.PIDFile`. """ + self._drop_privileges() + Daemonizer(cherrypy.engine).subscribe() + PIDFile(cherrypy.engine, self.setup['daemon']).subscribe() + return True + + def _drop_privileges(self): + """ Drop privileges with + :class:`cherrypy.process.plugins.DropPrivileges` """ DropPrivileges(cherrypy.engine, uid=self.setup['daemon_uid'], gid=self.setup['daemon_gid'], umask=int(self.setup['umask'], 8)).subscribe() - Daemonizer(cherrypy.engine).subscribe() - PIDFile(cherrypy.engine, self.setup['daemon']).subscribe() - return True def _run(self): """ Start the server listening. """ diff --git a/src/lib/Bcfg2/Server/Core.py b/src/lib/Bcfg2/Server/Core.py index 6dfe4df1f..0369da8f2 100644 --- a/src/lib/Bcfg2/Server/Core.py +++ b/src/lib/Bcfg2/Server/Core.py @@ -11,6 +11,7 @@ import threading import time import inspect import lxml.etree +import daemon import Bcfg2.settings import Bcfg2.Server import Bcfg2.Logger @@ -112,6 +113,7 @@ class BaseCore(object): :type setup: Bcfg2.Options.OptionParser .. automethod:: _daemonize + .. automethod:: _drop_privileges .. automethod:: _run .. automethod:: _block .. ----- @@ -803,7 +805,8 @@ class BaseCore(object): self.logger.debug("Slept %s seconds while handling FAM events" % slept) def run(self): - """ Run the server core. This calls :func:`_daemonize`, + """ Run the server core. This calls :func:`_daemonize` + (or :func:`_drop_privileges` if not in daemon mode), :func:`_run`, starts the :attr:`fam_thread`, and calls :func:`_block`, but note that it is the responsibility of the server core implementation to call :func:`shutdown` under @@ -830,6 +833,8 @@ class BaseCore(object): # dropped os.environ['HOME'] = pwd.getpwuid(self.setup['daemon_uid'])[5] else: + if os.getuid() == 0: + self._drop_privileges() os.umask(int(self.setup['umask'], 8)) if not self._run(): @@ -861,6 +866,16 @@ class BaseCore(object): overridden by a core implementation. """ raise NotImplementedError + def _drop_privileges(self): + """ This is called if not daemonized and running as root to + drop the privileges to the configured daemon_uid and daemon_gid. + """ + daemon.daemon.change_process_owner( + self.setup['daemon_uid'], + self.setup['daemon_gid']) + self.logger.debug("Dropped privileges to %s:%s." % + (os.getuid(), os.getgid())) + def _run(self): """ Start up the server; this method should return immediately. This must be overridden by a core diff --git a/src/lib/Bcfg2/Server/MultiprocessingCore.py b/src/lib/Bcfg2/Server/MultiprocessingCore.py index 2cb3adae3..4986aac60 100644 --- a/src/lib/Bcfg2/Server/MultiprocessingCore.py +++ b/src/lib/Bcfg2/Server/MultiprocessingCore.py @@ -210,6 +210,9 @@ class ChildCore(BaseCore): def _daemonize(self): return True + def _drop_privileges(self): + pass + def _dispatch(self, address, data): """ Method dispatcher used for commands received from the RPC queue. """ diff --git a/src/sbin/bcfg2-info b/src/sbin/bcfg2-info index a6c3149bc..2c97a9b91 100755 --- a/src/sbin/bcfg2-info +++ b/src/sbin/bcfg2-info @@ -726,6 +726,8 @@ Bcfg2 client itself.""") def run(self, args): # pylint: disable=W0221 try: + if os.getuid() == 0: + self._drop_privileges() self.load_plugins() self.block_for_fam_events(handle_events=True) if args: -- cgit v1.2.3-1-g7c22 From 9bc7bc153452dd0d6f624942fff207d18916feb8 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Tue, 17 Mar 2015 11:39:41 -0500 Subject: Reporting/models.py: Fix typo Signed-off-by: Sol Jerome --- src/lib/Bcfg2/Reporting/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Bcfg2/Reporting/models.py b/src/lib/Bcfg2/Reporting/models.py index 71fa66086..29f08e787 100644 --- a/src/lib/Bcfg2/Reporting/models.py +++ b/src/lib/Bcfg2/Reporting/models.py @@ -628,7 +628,7 @@ class POSIXGroupEntry(SuccessEntry): class PackageEntry(SuccessEntry): """ The new model for package information """ - # if this is an extra entry trget_version will be empty + # if this is an extra entry target_version will be empty target_version = models.CharField(max_length=1024, default='') current_version = models.CharField(max_length=1024) verification_details = models.TextField(default="") -- cgit v1.2.3-1-g7c22 From c8863b9a2dadacdacf433cbb818735c32e8f83a8 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Thu, 19 Mar 2015 09:35:48 -0500 Subject: APT.py: Fix syntax error introduced in cae39b7 Signed-off-by: Sol Jerome --- src/lib/Bcfg2/Client/Tools/APT.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Bcfg2/Client/Tools/APT.py b/src/lib/Bcfg2/Client/Tools/APT.py index 3c511681f..1d9b0dd70 100644 --- a/src/lib/Bcfg2/Client/Tools/APT.py +++ b/src/lib/Bcfg2/Client/Tools/APT.py @@ -54,7 +54,7 @@ class APT(Bcfg2.Client.Tools.Tool): [entry.get('name') for struct in config for entry in struct if (entry.tag == 'Path' and entry.get('name').startswith( - '%s/apt/sources.list' % self.etc_path)] + '%s/apt/sources.list' % self.etc_path))] self.nonexistent = [entry.get('name') for struct in config for entry in struct if (entry.tag == 'Path' and -- cgit v1.2.3-1-g7c22 From 16d3e04cb80a975eef0e0ad6f0f6dc4800860d3c Mon Sep 17 00:00:00 2001 From: Michael Fenn Date: Thu, 19 Mar 2015 15:10:44 -0400 Subject: compat: use eval instead of ast.literal_eval on python 2.4 --- doc/development/compat.txt | 10 ++++++++++ src/lib/Bcfg2/Compat.py | 6 ++++++ src/lib/Bcfg2/Options.py | 4 ++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/doc/development/compat.txt b/doc/development/compat.txt index 8700c46d3..5ac08ea68 100644 --- a/doc/development/compat.txt +++ b/doc/development/compat.txt @@ -129,6 +129,8 @@ below, since some of these implementations may be feature-incomplete. +----------------+--------------------------------+--------------------------------------------+ | MutableMapping | :class:`UserDict.DictMixin` | :class:`collections.MutableMapping` (2.6+) | +----------------+--------------------------------+--------------------------------------------+ +| literal_eval | :func:`ast.literal_eval` | :func:`eval` | ++----------------+--------------------------------+--------------------------------------------+ walk_packages ~~~~~~~~~~~~~ @@ -171,6 +173,14 @@ mind. :class:`collections.MutableMapping` is available in Python 2.6+, and will be used if available. +literal_eval +~~~~~~~~~~~~ + +:func:`ast.literal_eval` is a safe version of :func:`eval` that will only +allow delaration of literal strings, ints, list, dicts, etc. This was +introduced in Python 2.6, and as such Python 2.4 uses the plain-old +:func:`eval`. + Other Symbols ------------- diff --git a/src/lib/Bcfg2/Compat.py b/src/lib/Bcfg2/Compat.py index b8a75a0c5..1c2420ccf 100644 --- a/src/lib/Bcfg2/Compat.py +++ b/src/lib/Bcfg2/Compat.py @@ -286,3 +286,9 @@ except NameError: def cmp(a, b): """ Py3k implementation of cmp() """ return (a > b) - (a < b) + +# ast was introduced in python 2.6 +try: + from ast import literal_eval +except ImportError: + literal_eval = eval diff --git a/src/lib/Bcfg2/Options.py b/src/lib/Bcfg2/Options.py index fdc34eb95..5653b29e5 100644 --- a/src/lib/Bcfg2/Options.py +++ b/src/lib/Bcfg2/Options.py @@ -1,6 +1,5 @@ """Option parsing library for utilities.""" -import ast import copy import getopt import grp @@ -13,6 +12,7 @@ import sys import Bcfg2.Client.Tools from Bcfg2.Compat import ConfigParser +from Bcfg2.Compat import literal_eval from Bcfg2.version import __version__ @@ -333,7 +333,7 @@ def colon_split(c_string): def dict_split(c_string): """ literally evaluate the option in order to allow for arbitrarily nested dictionaries """ - return ast.literal_eval(c_string) + return literal_eval(c_string) def get_bool(val): -- cgit v1.2.3-1-g7c22 From eb11693747aa069f97538b2d6fca97ac1d5e97bb Mon Sep 17 00:00:00 2001 From: Michael Fenn Date: Thu, 19 Mar 2015 15:37:43 -0400 Subject: doc: fix literal_eval entry in table and clarify header --- doc/development/compat.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/development/compat.txt b/doc/development/compat.txt index 5ac08ea68..14522b6b3 100644 --- a/doc/development/compat.txt +++ b/doc/development/compat.txt @@ -113,7 +113,7 @@ with Python 2.4 (and occasionally 2.5). Be sure to read the notes below, since some of these implementations may be feature-incomplete. +----------------+--------------------------------+--------------------------------------------+ -| Name | Python 2.4 | Python 2.4+ | +| Name | Python 2.4 | Python 2.5+ | +================+================================+============================================+ | formatdate | :func:`email.Utils.formatdate` | :func:`email.utils.formatdate` | +----------------+--------------------------------+--------------------------------------------+ @@ -129,7 +129,7 @@ below, since some of these implementations may be feature-incomplete. +----------------+--------------------------------+--------------------------------------------+ | MutableMapping | :class:`UserDict.DictMixin` | :class:`collections.MutableMapping` (2.6+) | +----------------+--------------------------------+--------------------------------------------+ -| literal_eval | :func:`ast.literal_eval` | :func:`eval` | +| literal_eval | :func:`eval` | :func:`ast.literal_eval` | +----------------+--------------------------------+--------------------------------------------+ walk_packages -- cgit v1.2.3-1-g7c22 From 72938c5ed7de6e3bb8a286f12e2dc486d83b2f51 Mon Sep 17 00:00:00 2001 From: Michael Fenn Date: Thu, 19 Mar 2015 16:36:58 -0400 Subject: doc: ast.literal_eval in is only in 2.6+ --- doc/development/compat.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/development/compat.txt b/doc/development/compat.txt index 14522b6b3..132bf67c0 100644 --- a/doc/development/compat.txt +++ b/doc/development/compat.txt @@ -129,7 +129,7 @@ below, since some of these implementations may be feature-incomplete. +----------------+--------------------------------+--------------------------------------------+ | MutableMapping | :class:`UserDict.DictMixin` | :class:`collections.MutableMapping` (2.6+) | +----------------+--------------------------------+--------------------------------------------+ -| literal_eval | :func:`eval` | :func:`ast.literal_eval` | +| literal_eval | :func:`eval` | :func:`ast.literal_eval`(2.6+) | +----------------+--------------------------------+--------------------------------------------+ walk_packages -- 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(-) 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 From 82b8b12f6bba17201376775fe90490bdcc8642df Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Mon, 30 Mar 2015 15:03:21 -0500 Subject: Packages/Yum.py: Fix dependency resolution logic This commit helps the internal YUM resolver to choose the latest version of a package to generate dependencies. Previously, we were simply iterating through the file so that the last instance listed always won (even if that instance was an older version with differing dependencies). Signed-off-by: Sol Jerome --- src/lib/Bcfg2/Server/Plugins/Packages/Yum.py | 103 ++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 2 deletions(-) diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py index 20b0e103d..789df79d5 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py @@ -1169,6 +1169,94 @@ class YumSource(Source): self.file_to_arch[self.escape_url(fullurl)] = arch return urls + # pylint: disable=R0911,R0912 + # disabling the pylint errors above because we are interesting in + # replicating the flow of the RPM code. + def _compare_rpm_versions(self, str1, str2): + """ Compare RPM versions. + + This is an attempt to reimplement RPM's rpmvercmp method in python. + + :param str1: package 1 version string + :param str2: package 2 version string + :return: 1 - str1 is newer than str2 + 0 - str1 and str2 are the same version + -1 - str2 is newer than str1""" + if str1 == str2: + return 0 + + front_strip_re = re.compile('^[^A-Za-z0-9~]+') + risdigit = re.compile('(^[0-9]+)') + risalpha = re.compile('(^[A-Za-z])') + lzeroes = re.compile('^0+') + + while len(str1) > 0 or len(str2) > 0: + str1 = front_strip_re.sub('', str1) + str2 = front_strip_re.sub('', str2) + + if len(str1) == 0 or len(str2) == 0: + break + + # handle the tilde separator + if str1[0] == '~' and str2[0] == '~': + str1 = str1[1:] + str2 = str2[1:] + elif str1[0] == '~': + return -1 + elif str2[0] == '~': + return 1 + + # grab continuous segments from each string + isnum = False + if risdigit.match(str1): + segment1 = risdigit.split(str1)[1] + str1 = risdigit.split(str1)[2] + if risdigit.match(str2): + segment2 = risdigit.split(str2)[1] + str2 = risdigit.split(str2)[2] + else: + segment2 = '' + isnum = True + else: + segment1 = risalpha.split(str1)[1] + str1 = risalpha.split(str1)[2] + if risalpha.match(str2): + segment2 = risalpha.split(str2)[1] + str2 = risalpha.split(str2)[2] + else: + segment2 = '' + + # numeric segments are always newer than alpha segments + if len(segment2) == 0: + if isnum: + return 1 + return -1 + + if isnum: + # discard leading zeroes + segment1 = lzeroes.sub('', segment1) + segment2 = lzeroes.sub('', segment2) + # higher number has more digits + if len(segment1) > len(segment2): + return 1 + elif len(segment2) > len(segment1): + return -1 + # do a simple string comparison + if segment1 > segment2: + return 1 + elif segment2 > segment1: + return -1 + + # if one of the strings is empty, the version of the longer + # string is higher + if len(str1) > len(str2): + return 1 + elif len(str2) > len(str1): + return -1 + else: + return 0 + # pylint: enable=R0911,R0912 + @Bcfg2.Server.Plugin.track_statistics() def read_files(self): """ When using the builtin yum parser, read and parse locally @@ -1237,13 +1325,24 @@ class YumSource(Source): if arch not in self.packages: self.packages[arch] = set() if arch not in self.deps: - self.deps[arch] = dict() + self.deps[arch] = {} if arch not in self.provides: - self.provides[arch] = dict() + self.provides[arch] = {} + versionmap = {} for pkg in data.getchildren(): if not pkg.tag.endswith('package'): continue pkgname = pkg.find(XP + 'name').text + vtag = pkg.find(XP + 'version') + version = "%s%s-%s" % (vtag.get('epoch'), vtag.get('ver'), + vtag.get('rel')) + if pkgname in self.packages[arch]: + # skip if version older than a previous version + if self._compare_rpm_versions(version, + versionmap[pkgname]) < 0: + continue + + versionmap[pkgname] = version self.packages[arch].add(pkgname) pdata = pkg.find(XP + 'format') -- cgit v1.2.3-1-g7c22 From f3e9378c975d401c061da14e8e60fb031182f289 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Tue, 31 Mar 2015 09:01:51 -0500 Subject: Yum.py: Compare epoch/version/release separately Signed-off-by: Sol Jerome --- src/lib/Bcfg2/Server/Plugins/Packages/Yum.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py index 789df79d5..20103820c 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py @@ -1334,15 +1334,24 @@ class YumSource(Source): continue pkgname = pkg.find(XP + 'name').text vtag = pkg.find(XP + 'version') - version = "%s%s-%s" % (vtag.get('epoch'), vtag.get('ver'), - vtag.get('rel')) + epoch = vtag.get('epoch') + version = vtag.get('ver') + release = vtag.get('rel') if pkgname in self.packages[arch]: # skip if version older than a previous version - if self._compare_rpm_versions(version, - versionmap[pkgname]) < 0: + if (self._compare_rpm_versions( + epoch, versionmap[pkgname]['epoch']) < 0): continue - - versionmap[pkgname] = version + elif (self._compare_rpm_versions( + version, versionmap[pkgname]['version']) < 0): + continue + elif (self._compare_rpm_versions( + release, versionmap[pkgname]['release']) < 0): + continue + versionmap[pkgname] = {} + versionmap[pkgname]['epoch'] = epoch + versionmap[pkgname]['version'] = version + versionmap[pkgname]['release'] = release self.packages[arch].add(pkgname) pdata = pkg.find(XP + 'format') -- cgit v1.2.3-1-g7c22 From a0cbcdab79d8cf3bdba5c5dc19178872b6a4b542 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Thu, 9 Apr 2015 15:10:39 -0500 Subject: FreeBSDInit: Fix __init__ call Signed-off-by: Sol Jerome --- src/lib/Bcfg2/Client/Tools/FreeBSDInit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Bcfg2/Client/Tools/FreeBSDInit.py b/src/lib/Bcfg2/Client/Tools/FreeBSDInit.py index 8ff26d8f3..917d3ccdb 100644 --- a/src/lib/Bcfg2/Client/Tools/FreeBSDInit.py +++ b/src/lib/Bcfg2/Client/Tools/FreeBSDInit.py @@ -16,7 +16,7 @@ class FreeBSDInit(Bcfg2.Client.Tools.SvcTool): __req__ = {'Service': ['name', 'status']} def __init__(self, logger, cfg, setup): - Bcfg2.Client.Tools.Tool.__init__(self, logger, cfg, setup) + Bcfg2.Client.Tools.SvcTool.__init__(self, logger, cfg, setup) if os.uname()[0] != 'FreeBSD': raise Bcfg2.Client.Tools.ToolInstantiationError -- cgit v1.2.3-1-g7c22 From 093cca0e120950be2a09156aad34f8fc36fdb2b9 Mon Sep 17 00:00:00 2001 From: Ross Smith Date: Wed, 15 Apr 2015 09:41:44 -0400 Subject: handle filesystem secontexts properly for contextless filesystems - adds 'secontext_ignore' under POSIX in the configuration file - short circuits on filesystems that are known not to support file labels - defaults to filesystems that have a genfs command in selinux reference policy - checks for Operation not supported while setting a file label - fixes #275 --- src/lib/Bcfg2/Client/Tools/POSIX/base.py | 42 +++++++++++++++++--------------- src/lib/Bcfg2/Options.py | 15 +++++++++++- 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/base.py b/src/lib/Bcfg2/Client/Tools/POSIX/base.py index 3d1358ce0..1786fa83a 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/base.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/base.py @@ -6,6 +6,7 @@ import pwd import grp import stat import copy +import errno import shutil import Bcfg2.Client.Tools import Bcfg2.Client.XML @@ -272,7 +273,7 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): rv &= self._apply_acl(defacl, path, posix1e.ACL_TYPE_DEFAULT) return rv - def _set_secontext(self, entry, path=None): + def _set_secontext(self, entry, path=None): # pylint: disable=R0911 """ set the SELinux context of the file on disk according to the config""" if not HAS_SELINUX: @@ -284,25 +285,28 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): if not context: # no context listed return True - - if context == '__default__': - try: + secontext = selinux.lgetfilecon(path)[1].split(":")[2] + if secontext in self.setup["posix_secontext_ignore"]: + return True + try: + if context == '__default__': selinux.restorecon(path) - rv = True - except OSError: - err = sys.exc_info()[1] - self.logger.error("POSIX: Failed to restore SELinux context " - "for %s: %s" % (path, err)) - rv = False - else: - try: - rv = selinux.lsetfilecon(path, context) == 0 - except OSError: - err = sys.exc_info()[1] - self.logger.error("POSIX: Failed to restore SELinux context " - "for %s: %s" % (path, err)) - rv = False - return rv + return True + else: + return selinux.lsetfilecon(path, context) == 0 + except OSError: + err = sys.exc_info()[1] + if err.errno == errno.EOPNOTSUPP: + # Operation not supported + if context != '__default__': + self.logger.debug("POSIX: Failed to set SELinux context " + "for %s: %s" % (path, err)) + return False + return True + err = sys.exc_info()[1] + self.logger.error("POSIX: Failed to set or restore SELinux " + "context for %s: %s" % (path, err)) + return False def _norm_gid(self, gid): """ This takes a group name or gid and returns the diff --git a/src/lib/Bcfg2/Options.py b/src/lib/Bcfg2/Options.py index 5653b29e5..4565ec9a3 100644 --- a/src/lib/Bcfg2/Options.py +++ b/src/lib/Bcfg2/Options.py @@ -1115,6 +1115,18 @@ CLIENT_POSIX_GID_BLACKLIST = \ default=[], cf=('POSIXUsers', 'gid_blacklist'), cook=list_split) +CLIENT_POSIX_SECONTEXT_IGNORE = \ + Option("secontext types to ignore labeling errors", + default=['anon_inodefs_t', 'bdev_t', 'binfmt_misc_fs_t', + 'capifs_t', 'configfs_t', 'cpusetfs_t', 'ecryptfs_t', + 'eventpollfs_t', 'futexfs_t', 'hugetlbfs_t', 'ibmasmfs_t', + 'inotifyfs_t', 'mvfs_t', 'nfsd_fs_t', 'oprofilefs_t', + 'ramfs_t', 'romfs_t', 'rpc_pipefs_t', 'spufs_t', + 'squash_t', 'vmblock_t', 'vxfs_t', 'xenfs_t', 'autofs_t', + 'cifs_t', 'dosfs_t', 'fusefs_t', 'iso9660_t', + 'removable_t', 'nfs_t'], + cf=('POSIX', 'secontext_ignore'), + cook=list_split) # Logging options LOGGING_FILE_PATH = \ @@ -1281,7 +1293,8 @@ DRIVER_OPTIONS = \ posix_uid_whitelist=CLIENT_POSIX_UID_WHITELIST, posix_gid_whitelist=CLIENT_POSIX_GID_WHITELIST, posix_uid_blacklist=CLIENT_POSIX_UID_BLACKLIST, - posix_gid_blacklist=CLIENT_POSIX_GID_BLACKLIST) + posix_gid_blacklist=CLIENT_POSIX_GID_BLACKLIST, + posix_secontext_ignore=CLIENT_POSIX_SECONTEXT_IGNORE) CLIENT_COMMON_OPTIONS = \ dict(extra=CLIENT_EXTRA_DISPLAY, -- cgit v1.2.3-1-g7c22 From 5da396483df0bfa68c947b00210d33b5dd686954 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Fri, 17 Apr 2015 07:44:00 -0500 Subject: Reporting: Fix typo Signed-off-by: Sol Jerome --- src/lib/Bcfg2/Reporting/Collector.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Bcfg2/Reporting/Collector.py b/src/lib/Bcfg2/Reporting/Collector.py index 8e2fe1cb1..8e8e8b1fa 100644 --- a/src/lib/Bcfg2/Reporting/Collector.py +++ b/src/lib/Bcfg2/Reporting/Collector.py @@ -105,7 +105,7 @@ class ReportingCollector(object): self.storage.__class__.__name__) self.storage.validate() except: - self.logger.error("Storage backed %s failed to validate: %s" % + self.logger.error("Storage backend %s failed to validate: %s" % (self.storage.__class__.__name__, traceback.format_exc().splitlines()[-1])) -- cgit v1.2.3-1-g7c22 From 45a63e8cf0bfc5de075ee68d54b492b30f59bc77 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Tue, 28 Apr 2015 08:59:23 -0500 Subject: Yum.py: Add debug log message Log a message to debug if the package is missing from the host's primary architecture package list (as per Chris's request). Signed-off-by: Sol Jerome --- src/lib/Bcfg2/Server/Plugins/Packages/Yum.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py index 4ee9cce52..0e4f93246 100644 --- a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py +++ b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py @@ -1293,6 +1293,8 @@ class YumSource(Source): package not in self.blacklist and (len(self.whitelist) == 0 or package in self.whitelist)) except KeyError: + self.logger.debug("Packages: Unable to find %s for arch %s" % + (package, arch[0])) return False is_package.__doc__ = Source.is_package.__doc__ -- cgit v1.2.3-1-g7c22 From 2c227205c8449f20e5b8bf4b2f9103fa04a643d1 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Fri, 8 May 2015 11:47:21 -0500 Subject: docs: TemplateHelper forgot how to sentence --- doc/server/plugins/connectors/templatehelper.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/server/plugins/connectors/templatehelper.txt b/doc/server/plugins/connectors/templatehelper.txt index 4b1f66aee..c392acda7 100644 --- a/doc/server/plugins/connectors/templatehelper.txt +++ b/doc/server/plugins/connectors/templatehelper.txt @@ -48,9 +48,9 @@ See ``examples/TemplateHelper`` for examples of helper modules. Usage ===== -Specific helpers can be referred to in -templates as ``metadata.TemplateHelper[]``. That accesses -a HelperModule object will have, as attributes, all symbols listed in +Specific helpers can be referred to in templates as +``metadata.TemplateHelper[]``. That returns a HelperModule +object which will have, as attributes, all symbols listed in ``__export__``. For example, consider this helper module:: __export__ = ["hello"] -- cgit v1.2.3-1-g7c22 From 451fcfb8962674738f4a274237af378c1fe8311f Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Thu, 11 Jun 2015 15:24:54 -0500 Subject: Reporting: Fix plus/minus Signed-off-by: Sol Jerome --- src/lib/Bcfg2/Reporting/templates/clients/detail.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/Bcfg2/Reporting/templates/clients/detail.html b/src/lib/Bcfg2/Reporting/templates/clients/detail.html index e890589a7..6732bb8c9 100644 --- a/src/lib/Bcfg2/Reporting/templates/clients/detail.html +++ b/src/lib/Bcfg2/Reporting/templates/clients/detail.html @@ -90,7 +90,7 @@ span.history_links a {

Bundle membership

-
[+]
+
[+]
{% endif %} @@ -127,7 +127,7 @@ span.history_links a {

Failed Entries — {{ interaction.failures.all|length }}

-
[+]
+
[+]
{% for failure in interaction.failures.all %} -- cgit v1.2.3-1-g7c22 From a8953fd3cc3c8587eade52f0c3362da833014f32 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Thu, 11 Jun 2015 15:25:38 -0500 Subject: doc: Add more 1.3.6 release notes Signed-off-by: Sol Jerome --- doc/releases/1.3.6.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/doc/releases/1.3.6.txt b/doc/releases/1.3.6.txt index f41320f1a..9ab024674 100644 --- a/doc/releases/1.3.6.txt +++ b/doc/releases/1.3.6.txt @@ -30,7 +30,14 @@ This is primarily a bugfix release. https://docs.djangoproject.com/en/1.7/ref/settings/#std:setting-OPTIONS +* SYSV: change instances of simplename to simplefile + + Previous configurations can be updated using the migration tool. + * Authentication: Reject passwd auth, if authentication is set to "cert" +* Server/Core: drop privileges even if not running as daemon +* Packages/Yum.py: Fix dependency resolution logic +* Handle filesystem secontexts properly for contextless filesystems Special thanks to the following contributors for this release: Michael -Fenn, Matt Kemp, Alexander Sulfrian, Jonathan Billings. +Fenn, Matt Kemp, Alexander Sulfrian, Jonathan Billings, Ross Smith. -- cgit v1.2.3-1-g7c22 From ee11ee47bf86b67db100d76932a912d8239fa9d9 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Thu, 11 Jun 2015 15:30:04 -0500 Subject: Version bump to 1.3.6 Signed-off-by: Sol Jerome --- debian/changelog | 6 ++++++ doc/conf.py | 2 +- misc/bcfg2-selinux.spec | 2 +- misc/bcfg2.spec | 2 +- osx/Makefile | 4 ++-- osx/macports/Portfile | 2 +- solaris-ips/MANIFEST.bcfg2-server.header | 2 +- solaris-ips/MANIFEST.bcfg2.header | 2 +- solaris-ips/Makefile | 2 +- solaris-ips/pkginfo.bcfg2 | 2 +- solaris-ips/pkginfo.bcfg2-server | 2 +- solaris/Makefile | 2 +- solaris/pkginfo.bcfg2 | 2 +- solaris/pkginfo.bcfg2-server | 2 +- src/lib/Bcfg2/Reporting/templates/base.html | 2 +- src/lib/Bcfg2/version.py | 2 +- 16 files changed, 22 insertions(+), 16 deletions(-) diff --git a/debian/changelog b/debian/changelog index 3879cc50a..492495c77 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +bcfg2 (1.3.6-0.0) unstable; urgency=low + + * New upstream release + + -- Sol Jerome Thu, 11 Jun 2015 15:30:04 -0500 + bcfg2 (1.3.5-0.0) unstable; urgency=low * New upstream release diff --git a/doc/conf.py b/doc/conf.py index 3e877ef80..0d1188c39 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -66,7 +66,7 @@ else: # The short X.Y version. version = '1.3' # The full version, including alpha/beta/rc tags. -release = '1.3.5' +release = '1.3.6' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/misc/bcfg2-selinux.spec b/misc/bcfg2-selinux.spec index c926a1d74..fe9608ed0 100644 --- a/misc/bcfg2-selinux.spec +++ b/misc/bcfg2-selinux.spec @@ -16,7 +16,7 @@ %global _pre_rc %{?_pre:.pre%{_pre}}%{?_rc:.rc%{_rc}} Name: bcfg2-selinux -Version: 1.3.5 +Version: 1.3.6 Release: 1%{?_pre_rc}%{?dist} Summary: Bcfg2 Client and Server SELinux policy diff --git a/misc/bcfg2.spec b/misc/bcfg2.spec index c2d3c3c90..aa97c8d20 100644 --- a/misc/bcfg2.spec +++ b/misc/bcfg2.spec @@ -29,7 +29,7 @@ Name: bcfg2 -Version: 1.3.5 +Version: 1.3.6 Release: 1%{?_pre_rc}%{?dist} Summary: A configuration management system diff --git a/osx/Makefile b/osx/Makefile index ee7b7d565..9fa9e56ce 100644 --- a/osx/Makefile +++ b/osx/Makefile @@ -29,9 +29,9 @@ SITELIBDIR = /Library/Python/${PYVERSION}/site-packages # an Info.plist file for packagemaker to look at for package creation # and substitute the version strings. Major/Minor versions can only be # integers (e.g. "1" and "00" for bcfg2 version 1.0.0. -BCFGVER = 1.3.5 +BCFGVER = 1.3.6 MAJOR = 1 -MINOR = 35 +MINOR = 36 default: clean client diff --git a/osx/macports/Portfile b/osx/macports/Portfile index cf6f33ddc..dbf0bb901 100644 --- a/osx/macports/Portfile +++ b/osx/macports/Portfile @@ -5,7 +5,7 @@ PortSystem 1.0 PortGroup python26 1.0 name bcfg2 -version 1.3.5 +version 1.3.6 categories sysutils python maintainers gmail.com:sol.jerome license BSD diff --git a/solaris-ips/MANIFEST.bcfg2-server.header b/solaris-ips/MANIFEST.bcfg2-server.header index 9e6774c87..a7a451707 100644 --- a/solaris-ips/MANIFEST.bcfg2-server.header +++ b/solaris-ips/MANIFEST.bcfg2-server.header @@ -1,4 +1,4 @@ license ../../LICENSE license=simplified_bsd set name=description value="Configuration management server" set name=pkg.summary value="Configuration management server" -set name=pkg.fmri value="pkg://bcfg2/bcfg2-server@1.3.5" +set name=pkg.fmri value="pkg://bcfg2/bcfg2-server@1.3.6" diff --git a/solaris-ips/MANIFEST.bcfg2.header b/solaris-ips/MANIFEST.bcfg2.header index 97c63107e..0f2fc42b8 100644 --- a/solaris-ips/MANIFEST.bcfg2.header +++ b/solaris-ips/MANIFEST.bcfg2.header @@ -1,5 +1,5 @@ license ../../LICENSE license=simplified_bsd set name=description value="Configuration management client" set name=pkg.summary value="Configuration management client" -set name=pkg.fmri value="pkg://bcfg2/bcfg2@1.3.5" +set name=pkg.fmri value="pkg://bcfg2/bcfg2@1.3.6" file usr/bin/bcfg2 group=bin mode=0755 owner=root path=usr/bin/bcfg2 diff --git a/solaris-ips/Makefile b/solaris-ips/Makefile index ec85dccc2..0320d9da3 100644 --- a/solaris-ips/Makefile +++ b/solaris-ips/Makefile @@ -1,6 +1,6 @@ #!/usr/bin/gmake -VERS=1.3.5-1 +VERS=1.3.6-1 PYVERSION := $(shell python -c "import sys; print sys.version[0:3]") default: clean package diff --git a/solaris-ips/pkginfo.bcfg2 b/solaris-ips/pkginfo.bcfg2 index 57ffaffb8..7fa7e1c65 100644 --- a/solaris-ips/pkginfo.bcfg2 +++ b/solaris-ips/pkginfo.bcfg2 @@ -1,7 +1,7 @@ PKG="SCbcfg2" NAME="bcfg2" ARCH="sparc" -VERSION="1.3.5" +VERSION="1.3.6" CATEGORY="application" VENDOR="Argonne National Labratory" EMAIL="bcfg-dev@mcs.anl.gov" diff --git a/solaris-ips/pkginfo.bcfg2-server b/solaris-ips/pkginfo.bcfg2-server index 50812c4a5..2ef50951d 100644 --- a/solaris-ips/pkginfo.bcfg2-server +++ b/solaris-ips/pkginfo.bcfg2-server @@ -1,7 +1,7 @@ PKG="SCbcfg2-server" NAME="bcfg2-server" ARCH="sparc" -VERSION="1.3.5" +VERSION="1.3.6" CATEGORY="application" VENDOR="Argonne National Labratory" EMAIL="bcfg-dev@mcs.anl.gov" diff --git a/solaris/Makefile b/solaris/Makefile index 7719d7017..a1369e85c 100644 --- a/solaris/Makefile +++ b/solaris/Makefile @@ -1,7 +1,7 @@ #!/usr/sfw/bin/gmake PYTHON="/usr/local/bin/python" -VERS=1.3.5-1 +VERS=1.3.6-1 export PYVERSION := $(shell $(PYTHON) -c "import sys; print sys.version[0:3]") default: clean package diff --git a/solaris/pkginfo.bcfg2 b/solaris/pkginfo.bcfg2 index 57ffaffb8..7fa7e1c65 100644 --- a/solaris/pkginfo.bcfg2 +++ b/solaris/pkginfo.bcfg2 @@ -1,7 +1,7 @@ PKG="SCbcfg2" NAME="bcfg2" ARCH="sparc" -VERSION="1.3.5" +VERSION="1.3.6" CATEGORY="application" VENDOR="Argonne National Labratory" EMAIL="bcfg-dev@mcs.anl.gov" diff --git a/solaris/pkginfo.bcfg2-server b/solaris/pkginfo.bcfg2-server index 50812c4a5..2ef50951d 100644 --- a/solaris/pkginfo.bcfg2-server +++ b/solaris/pkginfo.bcfg2-server @@ -1,7 +1,7 @@ PKG="SCbcfg2-server" NAME="bcfg2-server" ARCH="sparc" -VERSION="1.3.5" +VERSION="1.3.6" CATEGORY="application" VENDOR="Argonne National Labratory" EMAIL="bcfg-dev@mcs.anl.gov" diff --git a/src/lib/Bcfg2/Reporting/templates/base.html b/src/lib/Bcfg2/Reporting/templates/base.html index a367d8ccb..7589f404e 100644 --- a/src/lib/Bcfg2/Reporting/templates/base.html +++ b/src/lib/Bcfg2/Reporting/templates/base.html @@ -93,7 +93,7 @@ This is needed for Django versions less than 1.5
diff --git a/src/lib/Bcfg2/version.py b/src/lib/Bcfg2/version.py index 61ba7a405..dfacfce6b 100644 --- a/src/lib/Bcfg2/version.py +++ b/src/lib/Bcfg2/version.py @@ -2,7 +2,7 @@ import re -__version__ = "1.3.5" +__version__ = "1.3.6" class Bcfg2VersionInfo(tuple): # pylint: disable=E0012,R0924 -- cgit v1.2.3-1-g7c22