diff options
Diffstat (limited to 'src/lib/Bcfg2/Client/Tools/YUM.py')
-rw-r--r-- | src/lib/Bcfg2/Client/Tools/YUM.py | 163 |
1 files changed, 101 insertions, 62 deletions
diff --git a/src/lib/Bcfg2/Client/Tools/YUM.py b/src/lib/Bcfg2/Client/Tools/YUM.py index d1fcb0f4a..ade4da5b3 100644 --- a/src/lib/Bcfg2/Client/Tools/YUM.py +++ b/src/lib/Bcfg2/Client/Tools/YUM.py @@ -3,6 +3,7 @@ import copy import os.path import sys +import logging import yum import yum.packages import yum.rpmtrans @@ -10,8 +11,10 @@ import yum.callbacks import yum.Errors import yum.misc import rpmUtils.arch +import rpmUtils.miscutils import Bcfg2.Client.XML import Bcfg2.Client.Tools +import Bcfg2.Options def build_yname(pkgname, inst): @@ -65,13 +68,13 @@ class RPMDisplay(yum.rpmtrans.RPMBaseCallback): """We subclass the default RPM transaction callback so that we can control Yum's verbosity and pipe it through the right logger.""" - def __init__(self, logger): + def __init__(self): yum.rpmtrans.RPMBaseCallback.__init__(self) # we want to log events to *both* the Bcfg2 logger (which goes # to stderr or syslog or wherever the user wants it to go) # *and* the yum file logger, which will go to yum.log (ticket # #1103) - self.bcfg2_logger = logger + self.bcfg2_logger = logging.getLogger(self.__class__.__name__) self.state = None self.package = None @@ -110,13 +113,50 @@ class YumDisplay(yum.callbacks.ProcessTransBaseCallback): """Class to handle display of what step we are in the Yum transaction such as downloading packages, etc.""" - def __init__(self, logger): + def __init__(self): yum.callbacks.ProcessTransBaseCallback.__init__(self) - self.logger = logger + self.logger = logging.getLogger(self.__class__.__name__) class YUM(Bcfg2.Client.Tools.PkgTool): """Support for Yum packages.""" + + options = Bcfg2.Client.Tools.PkgTool.options + [ + Bcfg2.Options.BooleanOption( + cf=('YUM', 'pkg_checks'), default=True, dest="yum_pkg_checks", + help="Perform YUM package checks"), + Bcfg2.Options.BooleanOption( + cf=('YUM', 'pkg_verify'), default=True, dest="yum_pkg_verify", + help="Perform YUM package verify"), + Bcfg2.Options.BooleanOption( + cf=('YUM', 'install_missing'), default=True, + dest="yum_install_missing", + help="Install missing packages"), + Bcfg2.Options.Option( + cf=('YUM', 'erase_flags'), default=["allmatches"], + dest="yum_erase_flags", type=Bcfg2.Options.Types.comma_list, + help="YUM erase flags"), + Bcfg2.Options.BooleanOption( + cf=('YUM', 'fix_version'), default=True, + dest="yum_fix_version", + help="Fix (upgrade or downgrade) packages with the wrong version"), + Bcfg2.Options.BooleanOption( + cf=('YUM', 'reinstall_broken'), default=True, + dest="yum_reinstall_broken", + help="Reinstall packages that fail to verify"), + Bcfg2.Options.Option( + cf=('YUM', 'verify_flags'), default=[], + dest="yum_verify_flags", type=Bcfg2.Options.Types.comma_list, + help="YUM verify flags"), + Bcfg2.Options.Option( + cf=('YUM', 'disabled_plugins'), default=[], + type=Bcfg2.Options.Types.comma_list, dest="yum_disabled_plugins", + help="YUM disabled plugins"), + Bcfg2.Options.Option( + cf=('YUM', 'enabled_plugins'), default=[], + type=Bcfg2.Options.Types.comma_list, dest="yum_enabled_plugins", + help="YUM enabled plugins")] + pkgtype = 'yum' __execs__ = [] __handles__ = [('Package', 'yum'), @@ -126,11 +166,11 @@ class YUM(Bcfg2.Client.Tools.PkgTool): __req__ = {'Package': ['type'], 'Path': ['type']} - conflicts = ['YUM24', 'RPM', 'RPMng', 'YUMng'] + conflicts = ['RPM'] - def __init__(self, logger, setup, config): - self.yumbase = self._loadYumBase(setup=setup, logger=logger) - Bcfg2.Client.Tools.PkgTool.__init__(self, logger, setup, config) + def __init__(self, config): + self.yumbase = self._loadYumBase() + Bcfg2.Client.Tools.PkgTool.__init__(self, config) self.ignores = [] for struct in config: self.ignores.extend([entry.get('name') @@ -171,60 +211,56 @@ class YUM(Bcfg2.Client.Tools.PkgTool): else: dest[pname] = dict(data) - # Process the Yum section from the config file. These are all - # boolean flags, either we do stuff or we don't - self.pkg_checks = self.setup["yum_pkg_checks"] - self.pkg_verify = self.setup["yum_pkg_verify"] - self.do_install = self.setup["yum_installed_action"] == "install" - self.do_upgrade = self.setup["yum_version_fail_action"] == "upgrade" - self.do_reinst = self.setup["yum_verify_fail_action"] == "reinstall" - self.verify_flags = self.setup["yum_verify_flags"] - self.installonlypkgs = self.yumbase.conf.installonlypkgs if 'gpg-pubkey' not in self.installonlypkgs: self.installonlypkgs.append('gpg-pubkey') - self.logger.debug("Yum: Install missing: %s" % self.do_install) - self.logger.debug("Yum: pkg_checks: %s" % self.pkg_checks) - self.logger.debug("Yum: pkg_verify: %s" % self.pkg_verify) - self.logger.debug("Yum: Upgrade on version fail: %s" % self.do_upgrade) - self.logger.debug("Yum: Reinstall on verify fail: %s" % self.do_reinst) + self.logger.debug("Yum: Install missing: %s" % + Bcfg2.Options.setup.yum_install_missing) + self.logger.debug("Yum: pkg_checks: %s" % + Bcfg2.Options.setup.yum_pkg_checks) + self.logger.debug("Yum: pkg_verify: %s" % + Bcfg2.Options.setup.yum_pkg_verify) + self.logger.debug("Yum: Upgrade on version fail: %s" % + Bcfg2.Options.setup.yum_fix_version) + self.logger.debug("Yum: Reinstall on verify fail: %s" % + Bcfg2.Options.setup.yum_reinstall_broken) self.logger.debug("Yum: installonlypkgs: %s" % self.installonlypkgs) - self.logger.debug("Yum: verify_flags: %s" % self.verify_flags) - self.logger.debug("Yum: disabled_plugins: %s" % - self.setup["yum_disabled_plugins"]) - self.logger.debug("Yum: enabled_plugins: %s" % - self.setup["yum_enabled_plugins"]) - - def _loadYumBase(self, setup=None, logger=None): + self.logger.debug("Yum: verify_flags: %s" % + Bcfg2.Options.setup.yum_verify_flags) + self.logger.debug("Yum: disabled_plugins: %s" % + Bcfg2.Options.setup.yum_disabled_plugins) + self.logger.debug("Yum: enabled_plugins: %s" % + Bcfg2.Options.setup.yum_enabled_plugins) + + def _loadYumBase(self): ''' this may be called before PkgTool.__init__() is called on this object (when the YUM object is first instantiated; PkgTool.__init__() calls RefreshPackages(), which requires a YumBase object already exist), or after __init__() has completed, when we reload the yum config before installing - packages. Consequently, we support both methods by allowing - setup and logger, the only object properties we use in this - function, to be passed as keyword arguments or to be omitted - and drawn from the object itself.''' + packages. ''' rv = yum.YumBase() # pylint: disable=C0103 - if setup is None: - setup = self.setup - if logger is None: + if hasattr(self, "logger"): logger = self.logger + else: + logger = logging.getLogger(self.name) - if setup['debug']: + if Bcfg2.Options.setup.debug: debuglevel = 3 - elif setup['verbose']: + elif Bcfg2.Options.setup.verbose: debuglevel = 2 else: debuglevel = 0 - if setup['yum_disabled_plugins']: - rv.preconf.disabled_plugins = setup['yum_disabled_plugins'] + if len(Bcfg2.Options.setup.yum_disabled_plugins) > 0: + rv.preconf.disabled_plugins = \ + Bcfg2.Options.setup.yum_disabled_plugins - if setup['yum_enabled_plugins']: - rv.preconf.enabled_plugins = setup['yum_enabled_plugins'] + if len(Bcfg2.Options.setup.yum_enabled_plugins) > 0: + rv.preconf.enabled_plugins = \ + Bcfg2.Options.setup.yum_enabled_plugins # pylint: disable=E1121,W0212 try: @@ -252,7 +288,7 @@ class YUM(Bcfg2.Client.Tools.PkgTool): to the newest available """ # old style entry; synthesize Instances from current installed if (entry.get('name') not in self.yum_installed and - entry.get('name') not in self.yum_avail): + entry.get('name') not in self.yum_avail): # new entry; fall back to default entry.set('version', 'any') else: @@ -306,7 +342,7 @@ class YUM(Bcfg2.Client.Tools.PkgTool): missing = Bcfg2.Client.Tools.PkgTool.missing_attrs(self, entry) if (entry.get('name', None) is None and - entry.get('group', None) is None): + entry.get('group', None) is None): missing += ['name', 'group'] return missing @@ -321,7 +357,7 @@ class YUM(Bcfg2.Client.Tools.PkgTool): using. Disabling file checksums is a new feature yum 3.2.17-ish """ try: - return pkg.verify(fast=self.setup.get('quick', False)) + return pkg.verify(fast=Bcfg2.Options.setup.quick) except TypeError: # Older Yum API return pkg.verify() @@ -446,9 +482,9 @@ class YUM(Bcfg2.Client.Tools.PkgTool): package_fail = False qtext_versions = [] virt_pkg = False - pkg_checks = (self.pkg_checks and + pkg_checks = (Bcfg2.Options.setup.yum_pkg_checks and entry.get('pkg_checks', 'true').lower() == 'true') - pkg_verify = (self.pkg_verify and + pkg_verify = (Bcfg2.Options.setup.yum_pkg_verify and entry.get('pkg_verify', 'true').lower() == 'true') yum_group = False @@ -541,7 +577,7 @@ class YUM(Bcfg2.Client.Tools.PkgTool): inst.get('verify_flags').lower().replace(' ', ',').split(',') else: - verify_flags = self.verify_flags + verify_flags = Bcfg2.Options.setup.yum_verify_flags if 'arch' in nevra: # If arch is specified use it to select the package @@ -625,7 +661,7 @@ class YUM(Bcfg2.Client.Tools.PkgTool): 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: + if rpmUtils.miscutils.compareEVR(current_evr, wanted_evr) == 1: entry.set("package_fail_action", "downgrade") else: entry.set("package_fail_action", "update") @@ -633,7 +669,7 @@ class YUM(Bcfg2.Client.Tools.PkgTool): qtext_versions.append("U(%s)" % str(all_pkg_objs[0])) continue - if self.setup.get('quick', False): + if Bcfg2.Options.setup.quick: # Passed -q on the command line continue if not (pkg_verify and @@ -707,7 +743,7 @@ class YUM(Bcfg2.Client.Tools.PkgTool): install_only = False if virt_pkg or \ - (install_only and not self.setup['kevlar']) or \ + (install_only and not Bcfg2.Options.setup.kevlar) or \ yum_group: # virtual capability supplied, we are probably dealing # with multiple packages of different names. This check @@ -830,8 +866,8 @@ class YUM(Bcfg2.Client.Tools.PkgTool): self.yumbase.closeRpmDB() self.RefreshPackages() - rpm_display = RPMDisplay(self.logger) - yum_display = YumDisplay(self.logger) + rpm_display = RPMDisplay() + yum_display = YumDisplay() # Run the Yum Transaction try: rescode, restring = self.yumbase.buildTransaction() @@ -880,7 +916,7 @@ class YUM(Bcfg2.Client.Tools.PkgTool): cleanup() - def Install(self, packages, states): # pylint: disable=R0912,R0914,R0915 + def Install(self, packages): # pylint: disable=R0912,R0914,R0915 """ Try and fix everything that Yum.VerifyPackages() found wrong for each Package Entry. This can result in individual RPMs being installed (for the first time), deleted, downgraded @@ -898,6 +934,7 @@ class YUM(Bcfg2.Client.Tools.PkgTool): entry is set to True. """ self.logger.debug('Running Yum.Install()') + states = dict() install_pkgs = [] gpg_keys = [] upgrade_pkgs = [] @@ -915,8 +952,7 @@ class YUM(Bcfg2.Client.Tools.PkgTool): # Remove extra instances. # Can not reverify because we don't have a package entry. if self.extra_instances is not None and len(self.extra_instances) > 0: - if (self.setup.get('remove') == 'all' or - self.setup.get('remove') == 'packages'): + if Bcfg2.Options.setup.remove in ['all', 'packages']: self.Remove(self.extra_instances) else: self.logger.info("The following extra package instances will " @@ -941,14 +977,17 @@ 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 self.do_install: + 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 self.do_upgrade: + elif (status.get('version_fail', False) and + Bcfg2.Options.setup.yum_fix_version): 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: + elif (status.get('verify_fail', False) and + Bcfg2.Options.setup.yum_reinstall_broken): queue_pkg(pkg, inst, reinstall_pkgs) else: # Either there was no Install/Version/Verify @@ -1037,7 +1076,7 @@ class YUM(Bcfg2.Client.Tools.PkgTool): self._runYumTransaction() - if not self.setup['kevlar']: + if not Bcfg2.Options.setup.kevlar: for pkg_entry in [p for p in packages if self.canVerify(p)]: self.logger.debug("Reverifying Failed Package %s" % pkg_entry.get('name')) @@ -1045,8 +1084,8 @@ class YUM(Bcfg2.Client.Tools.PkgTool): self.VerifyPackage(pkg_entry, self.modlists.get(pkg_entry, [])) - for entry in [ent for ent in packages if states[ent]]: - self.modified.append(entry) + self.modified.extend(ent for ent in packages if states[ent]) + return states def Remove(self, packages): """ |