diff options
Diffstat (limited to 'src/lib/Bcfg2/Client')
-rw-r--r-- | src/lib/Bcfg2/Client/Client.py | 1 | ||||
-rw-r--r-- | src/lib/Bcfg2/Client/Frame.py | 3 | ||||
-rw-r--r-- | src/lib/Bcfg2/Client/Proxy.py | 10 | ||||
-rw-r--r-- | src/lib/Bcfg2/Client/Tools/APT.py | 9 | ||||
-rw-r--r-- | src/lib/Bcfg2/Client/Tools/POSIX/base.py | 2 | ||||
-rw-r--r-- | src/lib/Bcfg2/Client/Tools/Portage.py | 3 | ||||
-rw-r--r-- | src/lib/Bcfg2/Client/Tools/RcUpdate.py | 12 | ||||
-rw-r--r-- | src/lib/Bcfg2/Client/Tools/VCS.py | 3 | ||||
-rw-r--r-- | src/lib/Bcfg2/Client/Tools/YUM.py | 84 | ||||
-rw-r--r-- | src/lib/Bcfg2/Client/Tools/__init__.py | 15 |
10 files changed, 112 insertions, 30 deletions
diff --git a/src/lib/Bcfg2/Client/Client.py b/src/lib/Bcfg2/Client/Client.py index e2521c0f8..66c1ce430 100644 --- a/src/lib/Bcfg2/Client/Client.py +++ b/src/lib/Bcfg2/Client/Client.py @@ -105,6 +105,7 @@ class Client(object): self._probe_failure(name, "Return value %s" % rv) self.logger.info("Probe %s has result:" % name) self.logger.info(rv.stdout) + ret.text = rv.stdout finally: os.unlink(scriptname) except SystemExit: diff --git a/src/lib/Bcfg2/Client/Frame.py b/src/lib/Bcfg2/Client/Frame.py index 82512130c..6ef686c10 100644 --- a/src/lib/Bcfg2/Client/Frame.py +++ b/src/lib/Bcfg2/Client/Frame.py @@ -481,7 +481,8 @@ class Frame(object): len(list(self.states.values()))) self.logger.info('Unmanaged entries: %d' % len(self.extra)) if phase == 'final' and self.setup['extra']: - for entry in self.extra: + for entry in sorted(self.extra, key=lambda e: e.tag + ":" + + e.get('name')): etype = entry.get('type') if etype: self.logger.info("%s:%s:%s" % (entry.tag, etype, diff --git a/src/lib/Bcfg2/Client/Proxy.py b/src/lib/Bcfg2/Client/Proxy.py index 1276c3ce9..f8817bb27 100644 --- a/src/lib/Bcfg2/Client/Proxy.py +++ b/src/lib/Bcfg2/Client/Proxy.py @@ -1,6 +1,6 @@ -import logging import re import socket +import logging # The ssl module is provided by either Python 2.6 or a separate ssl # package that works on older versions of Python (see @@ -20,7 +20,7 @@ import sys import time # Compatibility imports -from Bcfg2.Compat import httplib, xmlrpclib, urlparse +from Bcfg2.Compat import httplib, xmlrpclib, urlparse, quote_plus version = sys.version_info[:2] has_py26 = version >= (2, 6) @@ -51,13 +51,16 @@ class ProxyError(Exception): msg = str(err) Exception.__init__(self, msg) + class CertificateError(Exception): def __init__(self, commonName): self.commonName = commonName + def __str__(self): return ("Got unallowed commonName %s from server" % self.commonName) + _orig_Method = xmlrpclib._Method class RetryMethod(xmlrpclib._Method): @@ -350,7 +353,8 @@ def ComponentProxy(url, user=None, password=None, key=None, cert=None, ca=None, if user and password: method, path = urlparse(url)[:2] - newurl = "%s://%s:%s@%s" % (method, user, password, path) + newurl = "%s://%s:%s@%s" % (method, quote_plus(user, ''), + quote_plus(password, ''), path) else: newurl = url ssl_trans = XMLRPCTransport(key, cert, ca, diff --git a/src/lib/Bcfg2/Client/Tools/APT.py b/src/lib/Bcfg2/Client/Tools/APT.py index cc2f657d0..f449557aa 100644 --- a/src/lib/Bcfg2/Client/Tools/APT.py +++ b/src/lib/Bcfg2/Client/Tools/APT.py @@ -228,8 +228,13 @@ class APT(Bcfg2.Client.Tools.Tool): continue if pkg.get('version') in ['auto', 'any']: if self._newapi: - ipkgs.append("%s=%s" % (pkg.get('name'), - self.pkg_cache[pkg.get('name')].candidate.version)) + try: + ipkgs.append("%s=%s" % (pkg.get('name'), + self.pkg_cache[pkg.get('name')].candidate.version)) + except AttributeError: + self.logger.error("Failed to find %s in apt package cache" % + pkg.get('name')) + continue else: ipkgs.append("%s=%s" % (pkg.get('name'), self.pkg_cache[pkg.get('name')].candidateVersion)) diff --git a/src/lib/Bcfg2/Client/Tools/POSIX/base.py b/src/lib/Bcfg2/Client/Tools/POSIX/base.py index b867fa3d8..f46875743 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIX/base.py +++ b/src/lib/Bcfg2/Client/Tools/POSIX/base.py @@ -687,7 +687,7 @@ class POSIXTool(Bcfg2.Client.Tools.Tool): if path is None: path = entry.get("name") cur = path - while cur != '/': + while cur and cur != '/': if not os.path.exists(cur): created.append(cur) cur = os.path.dirname(cur) diff --git a/src/lib/Bcfg2/Client/Tools/Portage.py b/src/lib/Bcfg2/Client/Tools/Portage.py index aa1254b46..32afa8cbf 100644 --- a/src/lib/Bcfg2/Client/Tools/Portage.py +++ b/src/lib/Bcfg2/Client/Tools/Portage.py @@ -36,7 +36,8 @@ class Portage(Bcfg2.Client.Tools.PkgTool): return self.logger.info('Getting list of installed packages') self.installed = {} - for pkg in self.cmd.run("equery -q list '*'").stdout.splitlines(): + for pkg in self.cmd.run(["equery", "-q", + "list", "*"]).stdout.splitlines(): if self._pkg_pattern.match(pkg): name = self._pkg_pattern.match(pkg).group(1) version = self._pkg_pattern.match(pkg).group(2) diff --git a/src/lib/Bcfg2/Client/Tools/RcUpdate.py b/src/lib/Bcfg2/Client/Tools/RcUpdate.py index 2e58f2564..552b27842 100644 --- a/src/lib/Bcfg2/Client/Tools/RcUpdate.py +++ b/src/lib/Bcfg2/Client/Tools/RcUpdate.py @@ -22,8 +22,8 @@ class RcUpdate(Bcfg2.Client.Tools.SvcTool): return True # check if service is enabled - cmd = '/sbin/rc-update show default | grep %s' - is_enabled = self.cmd.run(cmd % entry.get('name')).success + result = self.cmd.run(["/sbin/rc-update", "show", "default"]) + is_enabled = entry.get("name") in result.stdout # check if init script exists try: @@ -34,8 +34,8 @@ class RcUpdate(Bcfg2.Client.Tools.SvcTool): return False # check if service is enabled - cmd = '/etc/init.d/%s status | grep started' - is_running = self.cmd.run(cmd % entry.attrib['name']).success + result = self.cmd.run(self.get_svc_command(entry, "status")) + is_running = "started" in result.stdout if entry.get('status') == 'on' and not (is_enabled and is_running): entry.set('current_status', 'off') @@ -70,9 +70,9 @@ class RcUpdate(Bcfg2.Client.Tools.SvcTool): def FindExtra(self): """Locate extra rc-update services.""" - cmd = '/bin/rc-status -s' allsrv = [line.split()[0] - for line in self.cmd.run(cmd).stdout.splitlines() + for line in self.cmd.run(['/bin/rc-status', + '-s']).stdout.splitlines() if 'started' in line] self.logger.debug('Found active services:') self.logger.debug(allsrv) diff --git a/src/lib/Bcfg2/Client/Tools/VCS.py b/src/lib/Bcfg2/Client/Tools/VCS.py index fa3d22e1d..1ab867215 100644 --- a/src/lib/Bcfg2/Client/Tools/VCS.py +++ b/src/lib/Bcfg2/Client/Tools/VCS.py @@ -120,8 +120,9 @@ class VCS(Bcfg2.Client.Tools.Tool): def Installsvn(self, entry): """Checkout contents from a svn repository""" # pylint: disable=E1101 + client = pysvn.Client() try: - client = pysvn.Client.update(entry.get('name'), recurse=True) + client.update(entry.get('name'), recurse=True) except pysvn.ClientError: self.logger.error("Failed to update repository", exc_info=1) return False diff --git a/src/lib/Bcfg2/Client/Tools/YUM.py b/src/lib/Bcfg2/Client/Tools/YUM.py index 648d30d15..57ca06e77 100644 --- a/src/lib/Bcfg2/Client/Tools/YUM.py +++ b/src/lib/Bcfg2/Client/Tools/YUM.py @@ -125,7 +125,7 @@ class YUM(Bcfg2.Client.Tools.PkgTool): ('Package', 'rpm'), ('Path', 'ignore')] - __req__ = {'Package': ['name'], + __req__ = {'Package': ['type'], 'Path': ['type']} conflicts = ['RPM'] @@ -290,6 +290,17 @@ class YUM(Bcfg2.Client.Tools.PkgTool): return self.yumbase.rpmdb.returnGPGPubkeyPackages() return self.yumbase.rpmdb.searchNevra(name='gpg-pubkey') + def missing_attrs(self, entry): + """ Implementing from superclass to check for existence of either + name or group attribute for Package entry in the case of a YUM + group. """ + missing = Bcfg2.Client.Tools.PkgTool.missing_attrs(self, entry) + + if entry.get('name', None) == None and \ + entry.get('group', None) == None: + missing += ['name', 'group'] + return missing + def _verifyHelper(self, pkg_obj): """ _verifyHelper primarly deals with a yum bug where the pkg_obj.verify() method does not properly take into count multilib @@ -412,8 +423,12 @@ class YUM(Bcfg2.Client.Tools.PkgTool): if entry.get('version', False) == 'auto': self._fixAutoVersion(entry) - self.logger.debug("Verifying package instances for %s" % - entry.get('name')) + if entry.get('group'): + self.logger.debug("Verifying packages for group %s" % + entry.get('group')) + else: + self.logger.debug("Verifying package instances for %s" % + entry.get('name')) self.verify_cache = dict() # Used for checking multilib packages self.modlists[entry] = modlist @@ -426,14 +441,58 @@ class YUM(Bcfg2.Client.Tools.PkgTool): entry.get('pkg_checks', 'true').lower() == 'true' pkg_verify = self.pkg_verify and \ entry.get('pkg_verify', 'true').lower() == 'true' + yum_group = False if entry.get('name') == 'gpg-pubkey': all_pkg_objs = self._getGPGKeysAsPackages() pkg_verify = False # No files here to verify + elif entry.get('group'): + entry.set('name', 'group:%s' % entry.get('group')) + yum_group = True + all_pkg_objs = [] + instances = [] + if self.yumbase.comps.has_group(entry.get('group')): + group = self.yumbase.comps.return_group(entry.get('group')) + group_packages = [p + for p, d in group.mandatory_packages.items() + if d] + group_type = entry.get('choose', 'default') + if group_type in ['default', 'optional', 'all']: + group_packages += [p + for p, d in + group.default_packages.items() + if d] + if group_type in ['optional', 'all']: + group_packages += [p + for p, d in + group.optional_packages.items() + if d] + if len(group_packages) == 0: + self.logger.error("No packages found for group %s" % + entry.get("group")) + for pkg in group_packages: + # create package instances for each package in yum group + instance = Bcfg2.Client.XML.SubElement(entry, 'Package') + instance.attrib['name'] = pkg + instance.attrib['type'] = 'yum' + try: + newest = \ + self.yumbase.pkgSack.returnNewestByName(pkg)[0] + instance.attrib['version'] = newest['version'] + instance.attrib['epoch'] = newest['epoch'] + instance.attrib['release'] = newest['release'] + except: # pylint: disable=W0702 + self.logger.info("Error finding newest package " + "for %s" % + pkg) + instance.attrib['version'] = 'any' + instances.append(instance) + else: + self.logger.error("Group not found: %s" % entry.get("group")) else: all_pkg_objs = \ self.yumbase.rpmdb.searchNevra(name=entry.get('name')) - if len(all_pkg_objs) == 0: + if len(all_pkg_objs) == 0 and yum_group != True: # Some sort of virtual capability? Try to resolve it all_pkg_objs = self.yumbase.rpmdb.searchProvides(entry.get('name')) if len(all_pkg_objs) > 0: @@ -444,7 +503,13 @@ class YUM(Bcfg2.Client.Tools.PkgTool): self.logger.info(" %s" % pkg) for inst in instances: - nevra = build_yname(entry.get('name'), inst) + if yum_group: + # the entry is not the name of the package + nevra = build_yname(inst.get('name'), inst) + all_pkg_objs = \ + self.yumbase.rpmdb.searchNevra(name=inst.get('name')) + else: + nevra = build_yname(entry.get('name'), inst) if nevra in pkg_cache: continue # Ignore duplicate instances else: @@ -458,7 +523,10 @@ class YUM(Bcfg2.Client.Tools.PkgTool): stat['version_fail'] = False stat['verify'] = {} stat['verify_fail'] = False - stat['pkg'] = entry + if yum_group: + stat['pkg'] = inst + else: + stat['pkg'] = entry stat['modlist'] = modlist if inst.get('verify_flags'): # this splits on either space or comma @@ -627,7 +695,9 @@ class YUM(Bcfg2.Client.Tools.PkgTool): else: install_only = False - if virt_pkg or (install_only and not self.setup['kevlar']): + if virt_pkg or \ + (install_only and not self.setup['kevlar']) or \ + yum_group: # virtual capability supplied, we are probably dealing # with multiple packages of different names. This check # doesn't make a lot of since in this case. diff --git a/src/lib/Bcfg2/Client/Tools/__init__.py b/src/lib/Bcfg2/Client/Tools/__init__.py index 39a664df1..473d2bf09 100644 --- a/src/lib/Bcfg2/Client/Tools/__init__.py +++ b/src/lib/Bcfg2/Client/Tools/__init__.py @@ -130,7 +130,6 @@ class Tool(object): raise ToolInstantiationError("%s: %s not executable" % (self.name, filename)) - def BundleUpdated(self, bundle): # pylint: disable=W0613 """ Callback that is invoked when a bundle has been updated. @@ -516,8 +515,8 @@ class SvcTool(Tool): :param service: The service entry to modify :type service: lxml.etree._Element - :returns: tuple - The return value from - :class:`Bcfg2.Client.Tools.Executor.run` + :returns: Bcfg2.Utils.ExecutorResult - The return value from + :class:`Bcfg2.Utils.Executor.run` """ self.logger.debug('Starting service %s' % service.get('name')) return self.cmd.run(self.get_svc_command(service, 'start')) @@ -527,8 +526,8 @@ class SvcTool(Tool): :param service: The service entry to modify :type service: lxml.etree._Element - :returns: tuple - The return value from - :class:`Bcfg2.Client.Tools.Executor.run` + :returns: Bcfg2.Utils.ExecutorResult - The return value from + :class:`Bcfg2.Utils.Executor.run` """ self.logger.debug('Stopping service %s' % service.get('name')) return self.cmd.run(self.get_svc_command(service, 'stop')) @@ -538,8 +537,8 @@ class SvcTool(Tool): :param service: The service entry to modify :type service: lxml.etree._Element - :returns: tuple - The return value from - :class:`Bcfg2.Client.Tools.Executor.run` + :returns: Bcfg2.Utils.ExecutorResult - The return value from + :class:`Bcfg2.Utils.Executor.run` """ self.logger.debug('Restarting service %s' % service.get('name')) restart_target = service.get('target', 'restart') @@ -553,7 +552,7 @@ class SvcTool(Tool): :returns: bool - True if the status command returned 0, False otherwise """ - return self.cmd.run(self.get_svc_command(service, 'status')) + return bool(self.cmd.run(self.get_svc_command(service, 'status'))) def Remove(self, services): if self.setup['servicemode'] != 'disabled': |