From 94ba31279869d7052ba001e38927f9eecd0a636f Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Tue, 10 Dec 2013 20:58:55 -0500 Subject: Augeas improvements: * Added ability to specify initial content for a file that doesn't exist, to avoid a messy situation where you'd have to probe for file existence and either use a Path type="file" or Path type="augeas" depending, and run Bcfg2 twice. * All commands in an Augeas path are run if *any* of them fail to verify. Previously, only commands that hadn't been run would be installed, but that had issues, particularly with the Clear command, which could pass verification but then be required during the installation phase anyway. * Miscellaneous bug fixes. --- src/lib/Bcfg2/Client/Tools/POSIX/Augeas.py | 31 ++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'src/lib/Bcfg2/Client/Tools') diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/Augeas.py b/src/lib/Bcfg2/Client/Tools/POSIX/Augeas.py index 81c948d0d..187b4d77c 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/Augeas.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/Augeas.py @@ -4,6 +4,7 @@ import sys import Bcfg2.Client.XML from augeas import Augeas from Bcfg2.Client.Tools.POSIX.base import POSIXTool +from Bcfg2.Client.Tools.POSIX.File import POSIXFile class AugeasCommand(object): @@ -187,13 +188,14 @@ class Insert(AugeasCommand): class POSIXAugeas(POSIXTool): """ Handle entries. See :ref:`client-tools-augeas`. """ - - __handles__ = [('Path', 'augeas')] - __req__ = {'Path': ['type', 'name', 'setting', 'value']} + __req__ = ['name', 'mode', 'owner', 'group'] def __init__(self, logger, setup, config): POSIXTool.__init__(self, logger, setup, config) self._augeas = dict() + # file tool for setting initial values of files that don't + # exist + self.filetool = POSIXFile(logger, setup, config) def get_augeas(self, entry): """ Get an augeas object for the given entry. """ @@ -214,9 +216,9 @@ class POSIXAugeas(POSIXTool): return self._augeas[entry.get("name")] def fully_specified(self, entry): - return entry.text is not None + return len(entry.getchildren()) != 0 - def get_commands(self, entry, unverified=False): + def get_commands(self, entry): """ Get a list of commands to verify or install. @param entry: The entry to get commands from. @@ -229,7 +231,7 @@ class POSIXAugeas(POSIXTool): """ rv = [] for cmd in entry.iterchildren(): - if unverified and cmd.get("verified", "false") != "false": + if cmd.tag == "Initial": continue if cmd.tag in globals(): rv.append(globals()[cmd.tag](cmd, self.get_augeas(entry), @@ -266,7 +268,17 @@ class POSIXAugeas(POSIXTool): def install(self, entry): rv = True - for cmd in self.get_commands(entry, unverified=True): + if entry.get("current_exists", "true") == "false": + initial = entry.find("Initial") + if initial is not None: + self.logger.debug("Augeas: Setting initial data for %s" % + entry.get("name")) + file_entry = Bcfg2.Client.XML.Element("Path", **entry.attrib) + file_entry.text = initial.text + self.filetool.install(file_entry) + # re-parse the file + self.get_augeas(entry).load() + for cmd in self.get_commands(entry): try: cmd.install() except: # pylint: disable=W0702 @@ -277,8 +289,7 @@ class POSIXAugeas(POSIXTool): try: self.get_augeas(entry).save() except: # pylint: disable=W0702 - self.logger.error( - "Failure saving Augeas changes to %s: %s" % - (entry.get("name"), sys.exc_info()[1])) + self.logger.error("Failure saving Augeas changes to %s: %s" % + (entry.get("name"), sys.exc_info()[1])) rv = False return POSIXTool.install(self, entry) and rv -- cgit v1.2.3-1-g7c22 From 053a87c6c496665a6dacab3efdecd4d7ebc2234d Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Sun, 5 Jan 2014 19:51:19 +0000 Subject: Fixed group blacklist issue #150 --- src/lib/Bcfg2/Client/Tools/POSIXUsers.py | 1 + 1 file changed, 1 insertion(+) (limited to 'src/lib/Bcfg2/Client/Tools') diff --git a/src/lib/Bcfg2/Client/Tools/POSIXUsers.py b/src/lib/Bcfg2/Client/Tools/POSIXUsers.py index bf23aca6b..161145a14 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIXUsers.py +++ b/src/lib/Bcfg2/Client/Tools/POSIXUsers.py @@ -147,6 +147,7 @@ class POSIXUsers(Bcfg2.Client.Tools.Tool): given entry is a member of """ return [g for g in self.existing['POSIXGroup'].values() if entry.get("name") in g[3] and g[0] != entry.get("group")] + and self._in_managed_range('POSIXGroup', g[2] def VerifyPOSIXUser(self, entry, _): """ Verify a POSIXUser entry """ -- cgit v1.2.3-1-g7c22 From 293fcb0b601fd8ce46c34b49b4b1b661f34a968f Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Sun, 5 Jan 2014 20:05:04 +0000 Subject: Fixed syntatical error in previous --- src/lib/Bcfg2/Client/Tools/POSIXUsers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/lib/Bcfg2/Client/Tools') diff --git a/src/lib/Bcfg2/Client/Tools/POSIXUsers.py b/src/lib/Bcfg2/Client/Tools/POSIXUsers.py index 161145a14..1bae94d28 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 g[0] != entry.get("group")] - and self._in_managed_range('POSIXGroup', g[2] + if entry.get("name") in g[3] and g[0] != entry.get("group") + and self._in_managed_range('POSIXGroup', g[2])] def VerifyPOSIXUser(self, entry, _): """ Verify a POSIXUser entry """ -- cgit v1.2.3-1-g7c22 From f3154b9f0471faaef0e64f89b669cd01614fef20 Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Sun, 5 Jan 2014 20:33:38 +0000 Subject: fixed indentation in previous --- src/lib/Bcfg2/Client/Tools/POSIXUsers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib/Bcfg2/Client/Tools') diff --git a/src/lib/Bcfg2/Client/Tools/POSIXUsers.py b/src/lib/Bcfg2/Client/Tools/POSIXUsers.py index 1bae94d28..6d18cd176 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIXUsers.py +++ b/src/lib/Bcfg2/Client/Tools/POSIXUsers.py @@ -147,7 +147,7 @@ class POSIXUsers(Bcfg2.Client.Tools.Tool): given entry is a member of """ return [g for g in self.existing['POSIXGroup'].values() if entry.get("name") in g[3] and g[0] != entry.get("group") - and self._in_managed_range('POSIXGroup', g[2])] + and self._in_managed_range('POSIXGroup', g[2])] def VerifyPOSIXUser(self, entry, _): """ Verify a POSIXUser entry """ -- cgit v1.2.3-1-g7c22 From f37833e5ea103796d5177a24901befd9b0f7ab28 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Thu, 16 Jan 2014 10:44:17 -0500 Subject: POSIX: Properly stringify ACLs with no user/group specified This is just a workaround to avoid a traceback; the real fix will involve making the POSIX tool properly handle ACLs with no user/group given, which refer to the current user/group of the file they apply to. --- src/lib/Bcfg2/Client/Tools/POSIX/base.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/lib/Bcfg2/Client/Tools') diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/base.py b/src/lib/Bcfg2/Client/Tools/POSIX/base.py index 85da3576b..3243bbf50 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/base.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/base.py @@ -395,7 +395,10 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): acl_str.append("user") elif scope == posix1e.ACL_GROUP: acl_str.append("group") - acl_str.append(qualifier) + if qualifier is None: + acl_str.append('') + else: + acl_str.append(qualifier) acl_str.append(self._acl_perm2string(perms)) return ":".join(acl_str) -- cgit v1.2.3-1-g7c22 From 9be8b7fb9eef3aa9cc7d44adb565dad7625ede4f Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Wed, 29 Jan 2014 16:33:33 -0500 Subject: Augeas: ensure that entry.attrib is always a dict --- src/lib/Bcfg2/Client/Tools/POSIX/Augeas.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/lib/Bcfg2/Client/Tools') diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/Augeas.py b/src/lib/Bcfg2/Client/Tools/POSIX/Augeas.py index 187b4d77c..8506f4bc7 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/Augeas.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/Augeas.py @@ -273,7 +273,8 @@ class POSIXAugeas(POSIXTool): if initial is not None: self.logger.debug("Augeas: Setting initial data for %s" % entry.get("name")) - file_entry = Bcfg2.Client.XML.Element("Path", **entry.attrib) + file_entry = Bcfg2.Client.XML.Element("Path", + **dict(entry.attrib)) file_entry.text = initial.text self.filetool.install(file_entry) # re-parse the file -- cgit v1.2.3-1-g7c22 From d19c0ced56af17132e902e1409129dd4ad96afb5 Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Tue, 4 Feb 2014 14:53:13 +0000 Subject: Support ACLs without a specific user/group for default owner/owning-group ACLs on directories --- src/lib/Bcfg2/Client/Tools/POSIX/base.py | 80 +++++++++++++++++++++----------- 1 file changed, 52 insertions(+), 28 deletions(-) (limited to 'src/lib/Bcfg2/Client/Tools') diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/base.py b/src/lib/Bcfg2/Client/Tools/POSIX/base.py index 3243bbf50..82e7c8fd8 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/base.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/base.py @@ -213,21 +213,19 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): # clear ACLs out so we start fresh -- way easier than trying # to add/remove/modify ACLs for aclentry in acl: - if aclentry.tag_type in [posix1e.ACL_USER, posix1e.ACL_GROUP]: + if aclentry.tag_type in [posix1e.ACL_USER, + posix1e.ACL_GROUP, + posix1e.ACL_OTHER]: acl.delete_entry(aclentry) if os.path.isdir(path): defacl = posix1e.ACL(filedef=path) - if not defacl.valid(): - # when a default ACL is queried on a directory that - # has no default ACL entries at all, you get an empty - # ACL, which is not valid. in this circumstance, we - # just copy the access ACL to get a base valid ACL - # that we can add things to. - defacl = posix1e.ACL(acl=acl) - else: + if defacl.valid(): for aclentry in defacl: if aclentry.tag_type in [posix1e.ACL_USER, - posix1e.ACL_GROUP]: + posix1e.ACL_USER_OBJ, + posix1e.ACL_GROUP, + posix1e.ACL_GROUP_OBJ, + posix1e.ACL_OTHER]: defacl.delete_entry(aclentry) else: defacl = None @@ -253,11 +251,17 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): aclentry.tag_type = scope try: if scope == posix1e.ACL_USER: - scopename = "user" - aclentry.qualifier = self._norm_uid(qualifier) + if qualifier: + scopename = "user" + aclentry.qualifier = self._norm_uid(qualifier) + else: + aclentry.tag_type = posix1e.ACL_USER_OBJ elif scope == posix1e.ACL_GROUP: - scopename = "group" - aclentry.qualifier = self._norm_gid(qualifier) + if qualifier: + scopename = "group" + aclentry.qualifier = self._norm_gid(qualifier) + else: + aclentry.tag_type = posix1e.ACL_GROUP_OBJ except (OSError, KeyError): err = sys.exc_info()[1] self.logger.error("POSIX: Could not resolve %s %s: %s" % @@ -358,7 +362,7 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): try: # single octal digit rv = int(perms) - if rv > 0 and rv < 8: + if rv >= 0 and rv < 8: return rv else: self.logger.error("POSIX: Permissions digit out of range in " @@ -388,17 +392,18 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): """ Get a string representation of the given ACL. aclkey must be a tuple of (, , ) """ atype, scope, qualifier = aclkey + if not qualifier: + qualifier = '' acl_str = [] if atype == 'default': acl_str.append(atype) - if scope == posix1e.ACL_USER: + if scope == posix1e.ACL_USER or scope == posix1e.ACL_USER_OBJ: acl_str.append("user") - elif scope == posix1e.ACL_GROUP: + elif scope == posix1e.ACL_GROUP or scope == posix1e.ACL_GROUP_OBJ: acl_str.append("group") - if qualifier is None: - acl_str.append('') - else: - acl_str.append(qualifier) + elif scope == posix1e.ACL_OTHER: + acl_str.append("other") + acl_str.append(qualifier) acl_str.append(self._acl_perm2string(perms)) return ":".join(acl_str) @@ -564,9 +569,17 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): wanted = dict() for acl in entry.findall("ACL"): if acl.get("scope") == "user": - scope = posix1e.ACL_USER + if acl.get("user"): + scope = posix1e.ACL_USER + else: + scope = posix1e.ACL_USER_OBJ elif acl.get("scope") == "group": - scope = posix1e.ACL_GROUP + if acl.get("group"): + scope = posix1e.ACL_GROUP + else: + scope = posix1e.ACL_GROUP_OBJ + elif acl.get("scope") == "other": + scope = posix1e.ACL_OTHER else: self.logger.error("POSIX: Unknown ACL scope %s" % acl.get("scope")) @@ -575,7 +588,10 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): self.logger.error("POSIX: No permissions set for ACL: %s" % Bcfg2.Client.XML.tostring(acl)) continue - wanted[(acl.get("type"), scope, acl.get(acl.get("scope")))] = \ + qual = acl.get(acl.get("scope")) + if not qual: + qual = '' + wanted[(acl.get("type"), scope, qual)] = \ self._norm_acl_perms(acl.get('perms')) return wanted @@ -589,11 +605,14 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): """ Given an ACL object, process it appropriately and add it to the return value """ try: + qual = '' if acl.tag_type == posix1e.ACL_USER: qual = pwd.getpwuid(acl.qualifier)[0] elif acl.tag_type == posix1e.ACL_GROUP: qual = grp.getgrgid(acl.qualifier)[0] - else: + elif atype == "access": + return + elif acl.tag_type == posix1e.ACL_MASK: return except (OSError, KeyError): err = sys.exc_info()[1] @@ -655,15 +674,20 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): atype, scope, qual = aclkey aclentry = Bcfg2.Client.XML.Element("ACL", type=atype, perms=str(perms)) - if scope == posix1e.ACL_USER: + if (scope == posix1e.ACL_USER or + scope == posix1e.ACL_USER_OBJ): aclentry.set("scope", "user") - elif scope == posix1e.ACL_GROUP: + elif (scope == posix1e.ACL_GROUP or + scope == posix1e.ACL_GROUP_OBJ): aclentry.set("scope", "group") + elif scope == posix1e.ACL_OTHER: + aclentry.set("scope", "other") else: self.logger.debug("POSIX: Unknown ACL scope %s on %s" % (scope, path)) continue - aclentry.set(aclentry.get("scope"), qual) + if scope != posix1e.ACL_OTHER: + aclentry.set(aclentry.get("scope"), qual) entry.append(aclentry) for aclkey, perms in existing.items(): -- cgit v1.2.3-1-g7c22 From a40c7fe2457688fd574558de7b8e31e9c30afb96 Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Tue, 4 Feb 2014 15:52:48 +0000 Subject: Minor changes to default ACL code --- src/lib/Bcfg2/Client/Tools/POSIX/base.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/lib/Bcfg2/Client/Tools') diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/base.py b/src/lib/Bcfg2/Client/Tools/POSIX/base.py index 82e7c8fd8..4ef4ae3f5 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/base.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/base.py @@ -251,14 +251,14 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): aclentry.tag_type = scope try: if scope == posix1e.ACL_USER: + scopename = "user" if qualifier: - scopename = "user" aclentry.qualifier = self._norm_uid(qualifier) else: aclentry.tag_type = posix1e.ACL_USER_OBJ elif scope == posix1e.ACL_GROUP: + scopename = "group" if qualifier: - scopename = "group" aclentry.qualifier = self._norm_gid(qualifier) else: aclentry.tag_type = posix1e.ACL_GROUP_OBJ @@ -610,9 +610,7 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): qual = pwd.getpwuid(acl.qualifier)[0] elif acl.tag_type == posix1e.ACL_GROUP: qual = grp.getgrgid(acl.qualifier)[0] - elif atype == "access": - return - elif acl.tag_type == posix1e.ACL_MASK: + elif atype == "access" or acl.tag_type == posix1e.ACL_MASK: return except (OSError, KeyError): err = sys.exc_info()[1] @@ -686,6 +684,7 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): self.logger.debug("POSIX: Unknown ACL scope %s on %s" % (scope, path)) continue + if scope != posix1e.ACL_OTHER: aclentry.set(aclentry.get("scope"), qual) entry.append(aclentry) -- cgit v1.2.3-1-g7c22 From d208eed80e048ea2081165c7aaaa92c558c38b25 Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Tue, 4 Feb 2014 16:03:17 +0000 Subject: fix for "Too many branches" in _verify_acls --- src/lib/Bcfg2/Client/Tools/POSIX/base.py | 43 +++++++++++++++++--------------- 1 file changed, 23 insertions(+), 20 deletions(-) (limited to 'src/lib/Bcfg2/Client/Tools') diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/base.py b/src/lib/Bcfg2/Client/Tools/POSIX/base.py index 4ef4ae3f5..4fb3c7b34 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/base.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/base.py @@ -643,26 +643,7 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): def _verify_acls(self, entry, path=None): """ verify POSIX ACLs on the given entry. return True if all ACLS are correct, false otherwise """ - if not HAS_ACLS: - if entry.findall("ACL"): - self.logger.debug("POSIX: ACLs listed for %s but no pylibacl " - "library installed" % entry.get('name')) - return True - - if path is None: - path = entry.get("name") - - # create lists of normalized representations of the ACLs we want - # and the ACLs we have. this will make them easier to compare - # than trying to mine that data out of the ACL objects and XML - # objects and compare it at the same time. - wanted = self._list_entry_acls(entry) - existing = self._list_file_acls(path) - - missing = [] - extra = [] - wrong = [] - for aclkey, perms in wanted.items(): + def _verify_acl(aclkey, perms): if aclkey not in existing: missing.append(self._acl2string(aclkey, perms)) elif existing[aclkey] != perms: @@ -689,6 +670,28 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): aclentry.set(aclentry.get("scope"), qual) entry.append(aclentry) + if not HAS_ACLS: + if entry.findall("ACL"): + self.logger.debug("POSIX: ACLs listed for %s but no pylibacl " + "library installed" % entry.get('name')) + return True + + if path is None: + path = entry.get("name") + + # create lists of normalized representations of the ACLs we want + # and the ACLs we have. this will make them easier to compare + # than trying to mine that data out of the ACL objects and XML + # objects and compare it at the same time. + wanted = self._list_entry_acls(entry) + existing = self._list_file_acls(path) + + missing = [] + extra = [] + wrong = [] + for aclkey, perms in wanted.items(): + _verify_acl(aclkey, perms) + for aclkey, perms in existing.items(): if aclkey not in wanted: extra.append(self._acl2string(aclkey, perms)) -- cgit v1.2.3-1-g7c22 From 310ec389a7542b8f7aeb807c6ed71ae7a82515d0 Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Tue, 4 Feb 2014 16:07:54 +0000 Subject: Fixed continue not in a loop error in previous --- src/lib/Bcfg2/Client/Tools/POSIX/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib/Bcfg2/Client/Tools') diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/base.py b/src/lib/Bcfg2/Client/Tools/POSIX/base.py index 4fb3c7b34..4089e9f22 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/base.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/base.py @@ -664,7 +664,7 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): else: self.logger.debug("POSIX: Unknown ACL scope %s on %s" % (scope, path)) - continue + return if scope != posix1e.ACL_OTHER: aclentry.set(aclentry.get("scope"), qual) -- cgit v1.2.3-1-g7c22 From b30cdb5330940c4606acbb83b057335be480552b Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Tue, 4 Feb 2014 16:20:24 +0000 Subject: Removed redundant condition for empty default ACL --- src/lib/Bcfg2/Client/Tools/POSIX/base.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src/lib/Bcfg2/Client/Tools') diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/base.py b/src/lib/Bcfg2/Client/Tools/POSIX/base.py index 4089e9f22..d230a5b3a 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/base.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/base.py @@ -219,14 +219,13 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): acl.delete_entry(aclentry) if os.path.isdir(path): defacl = posix1e.ACL(filedef=path) - if defacl.valid(): - for aclentry in defacl: - if aclentry.tag_type in [posix1e.ACL_USER, - posix1e.ACL_USER_OBJ, - posix1e.ACL_GROUP, - posix1e.ACL_GROUP_OBJ, - posix1e.ACL_OTHER]: - defacl.delete_entry(aclentry) + for aclentry in defacl: + if aclentry.tag_type in [posix1e.ACL_USER, + posix1e.ACL_USER_OBJ, + posix1e.ACL_GROUP, + posix1e.ACL_GROUP_OBJ, + posix1e.ACL_OTHER]: + defacl.delete_entry(aclentry) else: defacl = None -- cgit v1.2.3-1-g7c22 From bfdf4e9cac0c5d93cf7ce63513557847f005d5d2 Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Tue, 4 Feb 2014 16:59:44 +0000 Subject: Except _verify_acls from pylint branches check --- src/lib/Bcfg2/Client/Tools/POSIX/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib/Bcfg2/Client/Tools') diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/base.py b/src/lib/Bcfg2/Client/Tools/POSIX/base.py index d230a5b3a..d4051ba7f 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/base.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/base.py @@ -639,7 +639,7 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): _process_acl(acl, "default") return existing - def _verify_acls(self, entry, path=None): + def _verify_acls(self, entry, path=None): # pylint: disable=R0912 """ verify POSIX ACLs on the given entry. return True if all ACLS are correct, false otherwise """ def _verify_acl(aclkey, perms): -- cgit v1.2.3-1-g7c22 From 86f4766fd357c79956cd95b0506d1c85da96416d Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Tue, 4 Feb 2014 20:05:24 +0000 Subject: docstring for new sub-method --- src/lib/Bcfg2/Client/Tools/POSIX/base.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/lib/Bcfg2/Client/Tools') diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/base.py b/src/lib/Bcfg2/Client/Tools/POSIX/base.py index d4051ba7f..0eb9239c5 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/base.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/base.py @@ -643,6 +643,8 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): """ verify POSIX ACLs on the given entry. return True if all ACLS are correct, false otherwise """ def _verify_acl(aclkey, perms): + """ Given ACL data, process it appropriately and add it to + missing or wrong lists if appropriate """ if aclkey not in existing: missing.append(self._acl2string(aclkey, perms)) elif existing[aclkey] != perms: -- cgit v1.2.3-1-g7c22 From 75e1233c4ac292a554562b51475e972c647bd2b5 Mon Sep 17 00:00:00 2001 From: Richard Connon Date: Mon, 10 Feb 2014 17:32:57 +0000 Subject: Don't strip other entries from default ACL, these are defined by mode number. --- src/lib/Bcfg2/Client/Tools/POSIX/base.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/lib/Bcfg2/Client/Tools') diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/base.py b/src/lib/Bcfg2/Client/Tools/POSIX/base.py index 0eb9239c5..e593e0a0a 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/base.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/base.py @@ -213,9 +213,7 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): # clear ACLs out so we start fresh -- way easier than trying # to add/remove/modify ACLs for aclentry in acl: - if aclentry.tag_type in [posix1e.ACL_USER, - posix1e.ACL_GROUP, - posix1e.ACL_OTHER]: + if aclentry.tag_type in [posix1e.ACL_USER, posix1e.ACL_GROUP]: acl.delete_entry(aclentry) if os.path.isdir(path): defacl = posix1e.ACL(filedef=path) -- cgit v1.2.3-1-g7c22 From 58cee8566fba7b48d127227d96c98549b7db3028 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Mon, 10 Feb 2014 09:24:56 -0500 Subject: testsuite: Fixed several pylint 1.0 issues --- src/lib/Bcfg2/Client/Tools/VCS.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/lib/Bcfg2/Client/Tools') diff --git a/src/lib/Bcfg2/Client/Tools/VCS.py b/src/lib/Bcfg2/Client/Tools/VCS.py index aca5dbbc7..4fa2fb5e2 100644 --- a/src/lib/Bcfg2/Client/Tools/VCS.py +++ b/src/lib/Bcfg2/Client/Tools/VCS.py @@ -161,15 +161,19 @@ class VCS(Bcfg2.Client.Tools.Tool): def Verifysvn(self, entry, _): """Verify svn repositories""" - headrev = pysvn.Revision( pysvn.opt_revision_kind.head ) + # pylint: disable=E1101 + headrev = pysvn.Revision(pysvn.opt_revision_kind.head) + # pylint: enable=E1101 client = pysvn.Client() try: cur_rev = str(client.info(entry.get('name')).revision.number) - server = client.info2(entry.get('sourceurl'), headrev, recurse=False) + server = client.info2(entry.get('sourceurl'), headrev, + recurse=False) if server: server_rev = str(server[0][1].rev.number) except: - self.logger.info("Repository %s does not exist" % entry.get('name')) + self.logger.info("Repository %s does not exist" % + entry.get('name')) return False if entry.get('revision') == 'latest' and cur_rev == server_rev: -- cgit v1.2.3-1-g7c22 From cae2fcc0135c26811b1ce353ea28e4a93900c138 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Mon, 10 Feb 2014 09:02:16 -0500 Subject: POSIX: Fix verification of symlinks * Stat the link itself, not its target * Get SELinux context from the link, not the target * Don't get ACLs at all; symlinks don't have their own ACLs The first issue listed wasn't actually a bug, because none of the information queried from the target by the stat call was actually used in verification, but it's been fixed for completeness. --- src/lib/Bcfg2/Client/Tools/POSIX/base.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/lib/Bcfg2/Client/Tools') diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/base.py b/src/lib/Bcfg2/Client/Tools/POSIX/base.py index e593e0a0a..12f7f8a56 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/base.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/base.py @@ -419,7 +419,7 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): """ Get data on the existing state of -- e.g., whether or not it exists, owner, group, permissions, etc. """ try: - ondisk = os.stat(path) + ondisk = os.lstat(path) except OSError: self.logger.debug("POSIX: %s does not exist" % path) return (False, None, None, None, None, None) @@ -456,7 +456,7 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): if HAS_SELINUX: try: - secontext = selinux.getfilecon(path)[1].split(":")[2] + secontext = selinux.lgetfilecon(path)[1].split(":")[2] except (OSError, KeyError): err = sys.exc_info()[1] self.logger.debug("POSIX: Could not get current SELinux " @@ -465,7 +465,7 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): else: secontext = None - if HAS_ACLS: + if HAS_ACLS and not stat.S_ISLNK(ondisk): acls = self._list_file_acls(path) else: acls = None -- cgit v1.2.3-1-g7c22 From c51850b13f54d6f46e6c671e5ee1d3f0cacef727 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Tue, 25 Feb 2014 14:33:41 -0500 Subject: POSIX: fixed test to only apply ACLs to non-symlinks --- src/lib/Bcfg2/Client/Tools/POSIX/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/lib/Bcfg2/Client/Tools') diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/base.py b/src/lib/Bcfg2/Client/Tools/POSIX/base.py index 12f7f8a56..5fd3f2668 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/base.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/base.py @@ -1,4 +1,4 @@ -""" Base class for tools that handle POSIX (Path) entries """ +git """ Base class for tools that handle POSIX (Path) entries """ import os import sys @@ -465,7 +465,7 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): else: secontext = None - if HAS_ACLS and not stat.S_ISLNK(ondisk): + if HAS_ACLS and not stat.S_ISLNK(ondisk[stat.ST_MODE]): acls = self._list_file_acls(path) else: acls = None -- cgit v1.2.3-1-g7c22 From 38c8800814d5e09d40d7afb5aac4852e22776606 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Tue, 25 Feb 2014 14:42:56 -0500 Subject: Revert "POSIX: fixed test to only apply ACLs to non-symlinks" Massive typo. This reverts commit c51850b13f54d6f46e6c671e5ee1d3f0cacef727. --- src/lib/Bcfg2/Client/Tools/POSIX/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/lib/Bcfg2/Client/Tools') diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/base.py b/src/lib/Bcfg2/Client/Tools/POSIX/base.py index 5fd3f2668..12f7f8a56 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/base.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/base.py @@ -1,4 +1,4 @@ -git """ Base class for tools that handle POSIX (Path) entries """ +""" Base class for tools that handle POSIX (Path) entries """ import os import sys @@ -465,7 +465,7 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): else: secontext = None - if HAS_ACLS and not stat.S_ISLNK(ondisk[stat.ST_MODE]): + if HAS_ACLS and not stat.S_ISLNK(ondisk): acls = self._list_file_acls(path) else: acls = None -- cgit v1.2.3-1-g7c22 From 12edf6186b236006963b83ac8ffe174665e097b9 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Tue, 25 Feb 2014 14:43:50 -0500 Subject: POSIX: fixed test to only apply ACLs to non-symlinks --- src/lib/Bcfg2/Client/Tools/POSIX/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib/Bcfg2/Client/Tools') diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/base.py b/src/lib/Bcfg2/Client/Tools/POSIX/base.py index 12f7f8a56..3d1358ce0 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/base.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/base.py @@ -465,7 +465,7 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): else: secontext = None - if HAS_ACLS and not stat.S_ISLNK(ondisk): + if HAS_ACLS and not stat.S_ISLNK(ondisk[stat.ST_MODE]): acls = self._list_file_acls(path) else: acls = None -- cgit v1.2.3-1-g7c22 From bb873c4ab0848bc820db445938d4ff530173a062 Mon Sep 17 00:00:00 2001 From: Sol Jerome Date: Tue, 25 Mar 2014 14:14:25 -0500 Subject: Revert "Systemd: systemd is a replacement for chkconfig" This reverts commit 690a18b5bb61516e5c11f6da3d788332373c196b. While systemd is meant to replace chkconfig, it appears that RHEL7 has both and does not provide systemd alternatives for certain SYSV init scripts by default. --- src/lib/Bcfg2/Client/Tools/Systemd.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/lib/Bcfg2/Client/Tools') diff --git a/src/lib/Bcfg2/Client/Tools/Systemd.py b/src/lib/Bcfg2/Client/Tools/Systemd.py index 20a172d3d..027d91c71 100644 --- a/src/lib/Bcfg2/Client/Tools/Systemd.py +++ b/src/lib/Bcfg2/Client/Tools/Systemd.py @@ -13,8 +13,6 @@ class Systemd(Bcfg2.Client.Tools.SvcTool): __handles__ = [('Service', 'systemd')] __req__ = {'Service': ['name', 'status']} - conflicts = ['Chkconfig'] - def get_svc_command(self, service, action): return "/bin/systemctl %s %s.service" % (action, service.get('name')) -- cgit v1.2.3-1-g7c22 From 24a261f842a4bc1d4dc125fad0f43343d5d4c9d8 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Tue, 8 Apr 2014 15:03:54 -0400 Subject: Correctly upgrade or downgrade yum packages Formerly, yum did an 'update' to install the correct version of a package, even if the desired package was older than the installed package. This is wrong; it needs to do a downgrade. This changes it to downgrade when the desired package is older, and upgrade if it is newer. There is still the possibility of upgrading a package that should be downgraded if the desired package is only partially specified, but this should be very rare. --- src/lib/Bcfg2/Client/Tools/YUM.py | 51 +++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 15 deletions(-) (limited to 'src/lib/Bcfg2/Client/Tools') diff --git a/src/lib/Bcfg2/Client/Tools/YUM.py b/src/lib/Bcfg2/Client/Tools/YUM.py index c30c0a13a..b4ca32847 100644 --- a/src/lib/Bcfg2/Client/Tools/YUM.py +++ b/src/lib/Bcfg2/Client/Tools/YUM.py @@ -588,34 +588,38 @@ class YUM(Bcfg2.Client.Tools.PkgTool): package_fail = True stat['version_fail'] = True # Just chose the first pkg for the error message + current_pkg = all_pkg_objs[0] if virt_pkg: provides = \ - [p for p in all_pkg_objs[0].provides + [p for p in current_pkg.provides if p[0] == entry.get("name")][0] - entry.set('current_version', "%s:%s-%s" % provides[2]) + current_evr = provides[2] self.logger.info( " %s: Wrong version installed. " "Want %s, but %s provides %s" % (entry.get("name"), nevra2string(nevra), - nevra2string(all_pkg_objs[0]), + nevra2string(current_pkg), yum.misc.prco_tuple_to_string(provides))) else: - entry.set('current_version', "%s:%s-%s.%s" % - (all_pkg_objs[0].epoch, - all_pkg_objs[0].version, - all_pkg_objs[0].release, - all_pkg_objs[0].arch)) + current_evr = (current_pkg.epoch, + current_pkg.version, + current_pkg.release) self.logger.info(" %s: Wrong version installed. " "Want %s, but have %s" % (entry.get("name"), nevra2string(nevra), - nevra2string(all_pkg_objs[0]))) - entry.set('version', "%s:%s-%s.%s" % - (nevra.get('epoch', 'any'), - nevra.get('version', 'any'), - nevra.get('release', 'any'), - nevra.get('arch', 'any'))) + nevra2string(current_pkg))) + wanted_evr = (nevra.get('epoch', 'any'), + nevra.get('version', 'any'), + nevra.get('release', 'any')) + entry.set('current_version', "%s:%s-%s" % current_evr) + entry.set('version', "%s:%s-%s" % wanted_evr) + if yum.compareEVR(current_evr, wanted_evr) == 1: + entry.set("package_fail_action", "downgrade") + else: + entry.set("package_fail_action", "update") + qtext_versions.append("U(%s)" % str(all_pkg_objs[0])) continue @@ -887,6 +891,7 @@ class YUM(Bcfg2.Client.Tools.PkgTool): install_pkgs = [] gpg_keys = [] upgrade_pkgs = [] + downgrade_pkgs = [] reinstall_pkgs = [] def queue_pkg(pkg, inst, queue): @@ -929,7 +934,10 @@ class YUM(Bcfg2.Client.Tools.PkgTool): if not status.get('installed', False) and self.do_install: queue_pkg(pkg, inst, install_pkgs) elif status.get('version_fail', False) and self.do_upgrade: - queue_pkg(pkg, inst, upgrade_pkgs) + if pkg.get("package_fail_action") == "downgrade": + queue_pkg(pkg, inst, downgrade_pkgs) + else: + queue_pkg(pkg, inst, upgrade_pkgs) elif status.get('verify_fail', False) and self.do_reinst: queue_pkg(pkg, inst, reinstall_pkgs) else: @@ -992,6 +1000,19 @@ class YUM(Bcfg2.Client.Tools.PkgTool): self.logger.error("Error upgrading package %s: %s" % (pkg_arg, yume)) + if len(downgrade_pkgs) > 0: + self.logger.info("Attempting to downgrade packages") + + for inst in downgrade_pkgs: + pkg_arg = self.instance_status[inst].get('pkg').get('name') + self.logger.debug("Downgrading %s" % pkg_arg) + try: + self.yumbase.downgrade(**build_yname(pkg_arg, inst)) + except yum.Errors.YumBaseError: + yume = sys.exc_info()[1] + self.logger.error("Error downgrading package %s: %s" % + (pkg_arg, yume)) + if len(reinstall_pkgs) > 0: self.logger.info("Attempting to reinstall packages") for inst in reinstall_pkgs: -- cgit v1.2.3-1-g7c22