summaryrefslogtreecommitdiffstats
path: root/src/lib/Bcfg2/Client
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/Bcfg2/Client')
-rw-r--r--src/lib/Bcfg2/Client/Tools/APT.py102
-rw-r--r--src/lib/Bcfg2/Client/Tools/Action.py22
-rw-r--r--src/lib/Bcfg2/Client/Tools/POSIXUsers.py2
-rw-r--r--src/lib/Bcfg2/Client/Tools/SYSV.py43
-rw-r--r--src/lib/Bcfg2/Client/Tools/YUM.py4
-rw-r--r--src/lib/Bcfg2/Client/Tools/__init__.py20
6 files changed, 122 insertions, 71 deletions
diff --git a/src/lib/Bcfg2/Client/Tools/APT.py b/src/lib/Bcfg2/Client/Tools/APT.py
index cf4e7c7ea..9fcb7a3e0 100644
--- a/src/lib/Bcfg2/Client/Tools/APT.py
+++ b/src/lib/Bcfg2/Client/Tools/APT.py
@@ -5,6 +5,7 @@ import warnings
warnings.filterwarnings("ignore", "apt API not stable yet",
FutureWarning)
import os
+import sys
import apt.cache
import Bcfg2.Options
import Bcfg2.Client.Tools
@@ -12,7 +13,7 @@ import Bcfg2.Client.Tools
class APT(Bcfg2.Client.Tools.Tool):
"""The Debian toolset implements package and service operations
- and inherits the rest from Tools.Tool. """
+ and inherits the rest from Tools.Tool."""
options = Bcfg2.Client.Tools.Tool.options + [
Bcfg2.Options.PathOption(
@@ -79,10 +80,14 @@ class APT(Bcfg2.Client.Tools.Tool):
try:
self.pkg_cache = apt.cache.Cache()
except SystemError:
- e = sys.exc_info()[1]
- self.logger.info("Failed to initialize APT cache: %s" % e)
+ err = sys.exc_info()[1]
+ self.logger.info("Failed to initialize APT cache: %s" % err)
raise Bcfg2.Client.Tools.ToolInstantiationError
- self.pkg_cache.update()
+ try:
+ self.pkg_cache.update()
+ except apt.cache.FetchFailedException:
+ err = sys.exc_info()[1]
+ self.logger.info("Failed to update APT cache: %s" % err)
self.pkg_cache = apt.cache.Cache()
if 'req_reinstall_pkgs' in dir(self.pkg_cache):
self._newapi = True
@@ -103,9 +108,10 @@ class APT(Bcfg2.Client.Tools.Tool):
for (name, version) in extras]
def VerifyDebsums(self, entry, modlist):
+ """Verify the package contents with debsum information."""
output = \
self.cmd.run("%s -as %s" %
- (self.debsums, entry.get('name'))).stdout.splitlines()
+ (self.debsums, entry.get('name'))).stderr.splitlines()
if len(output) == 1 and "no md5sums for" in output[0]:
self.logger.info("Package %s has no md5sums. Cannot verify" %
entry.get('name'))
@@ -127,11 +133,11 @@ class APT(Bcfg2.Client.Tools.Tool):
# these files should not exist
continue
elif "is not installed" in item or "missing file" in item:
- self.logger.error("Package %s is not fully installed" %
- entry.get('name'))
+ self.logger.error("Package %s is not fully installed"
+ % entry.get('name'))
else:
- self.logger.error("Got Unsupported pattern %s from debsums" %
- item)
+ self.logger.error("Got Unsupported pattern %s from debsums"
+ % item)
files.append(item)
files = list(set(files) - set(self.ignores))
# We check if there is file in the checksum to do
@@ -142,30 +148,31 @@ class APT(Bcfg2.Client.Tools.Tool):
bad = [filename for filename in files if filename not in modlist]
if bad:
self.logger.debug("It is suggested that you either manage "
- "these files, revert the changes, or ignore "
- "false failures:")
- self.logger.info("Package %s failed validation. Bad files "
- "are:" % entry.get('name'))
+ "these files, revert the changes, or "
+ "ignore false failures:")
+ self.logger.info("Package %s failed validation. Bad files are:"
+ % entry.get('name'))
self.logger.info(bad)
- entry.set('qtext',
- "Reinstall Package %s-%s to fix failing files? "
- "(y/N) " % (entry.get('name'), entry.get('version')))
+ entry.set(
+ 'qtext',
+ "Reinstall Package %s-%s to fix failing files? (y/N) "
+ % (entry.get('name'), entry.get('version')))
return False
return True
def VerifyPackage(self, entry, modlist, checksums=True):
"""Verify package for entry."""
- if not 'version' in entry.attrib:
+ if 'version' not in entry.attrib:
self.logger.info("Cannot verify unversioned package %s" %
(entry.attrib['name']))
return False
pkgname = entry.get('name')
- if self.pkg_cache.has_key(pkgname): # nopep8
+ if self.pkg_cache.has_key(pkgname): # noqa
if self._newapi:
is_installed = self.pkg_cache[pkgname].is_installed
else:
is_installed = self.pkg_cache[pkgname].isInstalled
- if not self.pkg_cache.has_key(pkgname) or not is_installed: # nopep8
+ if not self.pkg_cache.has_key(pkgname) or not is_installed: # noqa
self.logger.info("Package %s not installed" % (entry.get('name')))
entry.set('current_exists', 'false')
return False
@@ -178,31 +185,33 @@ class APT(Bcfg2.Client.Tools.Tool):
installed_version = pkg.installedVersion
candidate_version = pkg.candidateVersion
if entry.get('version') == 'auto':
+ # pylint: disable=W0212
if self._newapi:
- is_upgradable = \
- self.pkg_cache._depcache.is_upgradable(pkg._pkg)
+ is_upgradable = self.pkg_cache._depcache.is_upgradable(
+ pkg._pkg)
else:
- is_upgradable = \
- self.pkg_cache._depcache.IsUpgradable(pkg._pkg)
+ is_upgradable = self.pkg_cache._depcache.IsUpgradable(
+ pkg._pkg)
+ # pylint: enable=W0212
if is_upgradable:
- desiredVersion = candidate_version
+ desired_version = candidate_version
else:
- desiredVersion = installed_version
+ desired_version = installed_version
elif entry.get('version') == 'any':
- desiredVersion = installed_version
+ desired_version = installed_version
else:
- desiredVersion = entry.get('version')
- if desiredVersion != installed_version:
+ desired_version = entry.get('version')
+ if desired_version != installed_version:
entry.set('current_version', installed_version)
entry.set('qtext', "Modify Package %s (%s -> %s)? (y/N) " %
(entry.get('name'), entry.get('current_version'),
- desiredVersion))
+ desired_version))
return False
else:
# version matches
- if (not Bcfg2.Options.setup.quick and
- entry.get('verify', 'true') == 'true'
- and checksums):
+ if not Bcfg2.Options.setup.quick \
+ and entry.get('verify', 'true') == 'true' \
+ and checksums:
pkgsums = self.VerifyDebsums(entry, modlist)
return pkgsums
return True
@@ -220,7 +229,7 @@ class APT(Bcfg2.Client.Tools.Tool):
self.pkg_cache[pkg].mark_delete(purge=True)
else:
self.pkg_cache[pkg].markDelete(purge=True)
- except:
+ except: # pylint: disable=W0702
if self._newapi:
self.pkg_cache[pkg].mark_delete()
else:
@@ -240,24 +249,26 @@ class APT(Bcfg2.Client.Tools.Tool):
ipkgs = []
bad_pkgs = []
for pkg in packages:
- if not self.pkg_cache.has_key(pkg.get('name')): # nopep8
- self.logger.error("APT has no information about package %s" %
- (pkg.get('name')))
+ if not self.pkg_cache.has_key(pkg.get('name')): # noqa
+ self.logger.error("APT has no information about package %s"
+ % (pkg.get('name')))
continue
if pkg.get('version') in ['auto', 'any']:
if self._newapi:
try:
- cversion = \
- self.pkg_cache[pkg.get('name')].candidate.version
- ipkgs.append("%s=%s" % (pkg.get('name'), cversion))
+ 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:
- cversion = self.pkg_cache[pkg.get('name')].candidateVersion
- ipkgs.append("%s=%s" % (pkg.get('name'), cversion))
+ ipkgs.append("%s=%s" % (
+ pkg.get('name'),
+ self.pkg_cache[pkg.get('name')].candidateVersion))
continue
+ # pylint: disable=W0212
if self._newapi:
avail_vers = [
x.ver_str for x in
@@ -266,13 +277,14 @@ class APT(Bcfg2.Client.Tools.Tool):
avail_vers = [
x.VerStr for x in
self.pkg_cache[pkg.get('name')]._pkg.VersionList]
+ # pylint: enable=W0212
if pkg.get('version') in avail_vers:
ipkgs.append("%s=%s" % (pkg.get('name'), pkg.get('version')))
continue
else:
- self.logger.error("Package %s: desired version %s not in %s" %
- (pkg.get('name'), pkg.get('version'),
- avail_vers))
+ self.logger.error("Package %s: desired version %s not in %s"
+ % (pkg.get('name'), pkg.get('version'),
+ avail_vers))
bad_pkgs.append(pkg.get('name'))
if bad_pkgs:
self.logger.error("Cannot find correct versions of packages:")
@@ -290,6 +302,6 @@ class APT(Bcfg2.Client.Tools.Tool):
self.modified.append(package)
return states
- def VerifyPath(self, entry, _):
+ def VerifyPath(self, entry, _): # pylint: disable=W0613
"""Do nothing here since we only verify Path type=ignore."""
return True
diff --git a/src/lib/Bcfg2/Client/Tools/Action.py b/src/lib/Bcfg2/Client/Tools/Action.py
index dedc50d89..ca0502b75 100644
--- a/src/lib/Bcfg2/Client/Tools/Action.py
+++ b/src/lib/Bcfg2/Client/Tools/Action.py
@@ -2,7 +2,6 @@
import Bcfg2.Client.Tools
from Bcfg2.Utils import safe_input
-from Bcfg2.Client import matches_white_list, passes_black_list
class Action(Bcfg2.Client.Tools.Tool):
@@ -11,23 +10,6 @@ class Action(Bcfg2.Client.Tools.Tool):
__handles__ = [('Action', None)]
__req__ = {'Action': ['name', 'timing', 'when', 'command', 'status']}
- def _action_allowed(self, action):
- """ Return true if the given action is allowed to be run by
- the whitelist or blacklist """
- if (Bcfg2.Options.setup.decision == 'whitelist' and
- not matches_white_list(action,
- Bcfg2.Options.setup.decision_list)):
- self.logger.info("In whitelist mode: suppressing Action: %s" %
- action.get('name'))
- return False
- if (Bcfg2.Options.setup.decision == 'blacklist' and
- not passes_black_list(action,
- Bcfg2.Options.setup.decision_list)):
- self.logger.info("In blacklist mode: suppressing Action: %s" %
- action.get('name'))
- return False
- return True
-
def RunAction(self, entry):
"""This method handles command execution and status return."""
shell = False
@@ -76,7 +58,7 @@ class Action(Bcfg2.Client.Tools.Tool):
states = dict()
for action in bundle.findall("Action"):
if action.get('timing') in ['post', 'both']:
- if not self._action_allowed(action):
+ if not self._install_allowed(action):
continue
states[action] = self.RunAction(action)
return states
@@ -87,7 +69,7 @@ class Action(Bcfg2.Client.Tools.Tool):
for action in bundle.findall("Action"):
if (action.get('timing') in ['post', 'both'] and
action.get('when') != 'modified'):
- if not self._action_allowed(action):
+ if not self._install_allowed(action):
continue
states[action] = self.RunAction(action)
return states
diff --git a/src/lib/Bcfg2/Client/Tools/POSIXUsers.py b/src/lib/Bcfg2/Client/Tools/POSIXUsers.py
index a7fcb6709..7200b0fc2 100644
--- a/src/lib/Bcfg2/Client/Tools/POSIXUsers.py
+++ b/src/lib/Bcfg2/Client/Tools/POSIXUsers.py
@@ -160,7 +160,7 @@ 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")
+ if entry.get("name") in g[3]
and self._in_managed_range('POSIXGroup', g[2])]
def VerifyPOSIXUser(self, entry, _):
diff --git a/src/lib/Bcfg2/Client/Tools/SYSV.py b/src/lib/Bcfg2/Client/Tools/SYSV.py
index 5698f237a..332638de4 100644
--- a/src/lib/Bcfg2/Client/Tools/SYSV.py
+++ b/src/lib/Bcfg2/Client/Tools/SYSV.py
@@ -4,6 +4,8 @@ import tempfile
from Bcfg2.Compat import any # pylint: disable=W0622
import Bcfg2.Client.Tools
import Bcfg2.Client.XML
+from Bcfg2.Compat import urlretrieve
+
# pylint: disable=C0103
noask = '''
@@ -37,6 +39,8 @@ class SYSV(Bcfg2.Client.Tools.PkgTool):
# noaskfile needs to live beyond __init__ otherwise file is removed
self.noaskfile = tempfile.NamedTemporaryFile()
self.noaskname = self.noaskfile.name
+ # for any pkg files downloaded
+ self.tmpfiles = []
try:
self.noaskfile.write(noask)
# flush admin file contents to disk
@@ -45,6 +49,41 @@ class SYSV(Bcfg2.Client.Tools.PkgTool):
self.pkgtool[1])
except: # pylint: disable=W0702
self.pkgtool = (self.pkgtool[0] % "", self.pkgtool[1])
+ self.origpkgtool = self.pkgtool
+
+ def pkgmogrify(self, packages):
+ """ Take a list of pkg objects, check for a 'simplefile' attribute.
+ If present, insert a _sysv_pkg_path attribute to the package and
+ download the datastream format SYSV package to a temporary file.
+ """
+ for pkg in packages:
+ if pkg.get('simplefile'):
+ tmpfile = tempfile.NamedTemporaryFile()
+ self.tmpfiles.append(tmpfile)
+ self.logger.info("Downloading %s to %s" % (pkg.get('url'),
+ tmpfile.name))
+ urlretrieve(pkg.get('url'), tmpfile.name)
+ pkg.set('_sysv_pkg_path', tmpfile.name)
+
+ def _get_package_command(self, packages):
+ """Override the default _get_package_command, replacing the attribute
+ 'url' if '_sysv_pkg_path' if necessary in the returned command
+ string
+ """
+ if hasattr(self, 'origpkgtool'):
+ if len(packages) == 1 and '_sysv_pkg_path' in packages[0].keys():
+ self.pkgtool = (self.pkgtool[0], ('%s %s',
+ ['_sysv_pkg_path', 'name']))
+ else:
+ self.pkgtool = self.origpkgtool
+
+ pkgcmd = super(SYSV, self)._get_package_command(packages)
+ self.logger.debug("Calling install command: %s" % pkgcmd)
+ return pkgcmd
+
+ def Install(self, packages):
+ self.pkgmogrify(packages)
+ super(SYSV, self).Install(packages)
def RefreshPackages(self):
"""Refresh memory hashes of packages."""
@@ -80,8 +119,8 @@ class SYSV(Bcfg2.Client.Tools.PkgTool):
self.logger.debug("Package %s not installed" %
entry.get("name"))
else:
- if (Bcfg2.Options.setup.quick or
- entry.attrib.get('verify', 'true') == 'false'):
+ if Bcfg2.Options.setup.quick or \
+ entry.attrib.get('verify', 'true') == 'false':
return True
rv = self.cmd.run("/usr/sbin/pkgchk -n %s" % entry.get('name'))
if rv.success:
diff --git a/src/lib/Bcfg2/Client/Tools/YUM.py b/src/lib/Bcfg2/Client/Tools/YUM.py
index b1caf3332..a8a80974a 100644
--- a/src/lib/Bcfg2/Client/Tools/YUM.py
+++ b/src/lib/Bcfg2/Client/Tools/YUM.py
@@ -977,8 +977,8 @@ class YUM(Bcfg2.Client.Tools.PkgTool):
nevra2string(build_yname(pkg.get('name'), inst)))
continue
status = self.instance_status[inst]
- if (not status.get('installed', False) and
- Bcfg2.Options.setup.yum_install_missing):
+ if not status.get('installed', False) and \
+ Bcfg2.Options.setup.yum_install_missing:
queue_pkg(pkg, inst, install_pkgs)
elif (status.get('version_fail', False) and
Bcfg2.Options.setup.yum_fix_version):
diff --git a/src/lib/Bcfg2/Client/Tools/__init__.py b/src/lib/Bcfg2/Client/Tools/__init__.py
index cd294db98..ae7fa3aed 100644
--- a/src/lib/Bcfg2/Client/Tools/__init__.py
+++ b/src/lib/Bcfg2/Client/Tools/__init__.py
@@ -129,6 +129,23 @@ class Tool(object):
raise ToolInstantiationError("%s: %s not executable" %
(self.name, filename))
+ def _install_allowed(self, entry):
+ """ Return true if the given entry is allowed to be installed by
+ the whitelist or blacklist """
+ if (Bcfg2.Options.setup.decision == 'whitelist' and
+ not Bcfg2.Client.matches_white_list(
+ entry, Bcfg2.Options.setup.decision_list)):
+ self.logger.info("In whitelist mode: suppressing Action: %s" %
+ entry.get('name'))
+ return False
+ if (Bcfg2.Options.setup.decision == 'blacklist' and
+ not Bcfg2.Client.passes_black_list(
+ entry, Bcfg2.Options.setup.decision_list)):
+ self.logger.info("In blacklist mode: suppressing Action: %s" %
+ entry.get('name'))
+ return False
+ return True
+
def BundleUpdated(self, bundle): # pylint: disable=W0613
""" Callback that is invoked when a bundle has been updated.
@@ -587,7 +604,8 @@ class SvcTool(Tool):
return
for entry in bundle:
- if not self.handlesEntry(entry):
+ if (not self.handlesEntry(entry)
+ or not self._install_allowed(entry)):
continue
estatus = entry.get('status')