diff options
author | Narayan Desai <desai@mcs.anl.gov> | 2007-04-11 01:48:10 +0000 |
---|---|---|
committer | Narayan Desai <desai@mcs.anl.gov> | 2007-04-11 01:48:10 +0000 |
commit | ada003add2413f90794ec43f6a3ea03d45d25072 (patch) | |
tree | 0d601eecd263d72bbd1c847db3c540ca20e616ea /src/lib/Client/Tools/YUMng.py | |
parent | 4bfd5a3087a085766681419e30544774ff41b944 (diff) | |
download | bcfg2-ada003add2413f90794ec43f6a3ea03d45d25072.tar.gz bcfg2-ada003add2413f90794ec43f6a3ea03d45d25072.tar.bz2 bcfg2-ada003add2413f90794ec43f6a3ea03d45d25072.zip |
Newest update to RPMng from mbrady
git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@3030 ce84e21b-d406-0410-9b95-82705330c041
Diffstat (limited to 'src/lib/Client/Tools/YUMng.py')
-rw-r--r-- | src/lib/Client/Tools/YUMng.py | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/src/lib/Client/Tools/YUMng.py b/src/lib/Client/Tools/YUMng.py new file mode 100644 index 000000000..cdc43b00b --- /dev/null +++ b/src/lib/Client/Tools/YUMng.py @@ -0,0 +1,343 @@ +'''This provides bcfg2 support for yum''' +__revision__ = '0.1' + +import Bcfg2.Client.Tools.RPMng, ConfigParser, sys + +try: + set +except NameError: + from sets import Set as set + +YAD = True +CP = ConfigParser.ConfigParser() +try: + if '-C' in sys.argv: + CP.read([sys.argv[sys.argv.index('-C') + 1]]) + else: + CP.read(['/etc/bcfg2.conf']) + if CP.get('YUMng', 'autodep') == 'false': + YAD = False +except: + pass + +class YUMng(Bcfg2.Client.Tools.RPMng.RPMng): + '''Support for Yum packages''' + pkgtype = 'yum' + + __name__ = 'YUMng' + __execs__ = ['/usr/bin/yum', '/var/lib/rpm'] + __handles__ = [('Package', 'yum'), ('Package', 'rpm')] + + __req__ = {'Package': ['name', 'version']} + __ireq__ = {'Package': ['name', 'version']} + + __new_req__ = {'Package': ['name'], 'Instance': ['version', 'release', 'arch']} + __new_ireq__ = {'Package': ['name', 'uri'], \ + 'Instance': ['simplefile', 'version', 'release', 'arch']} + + __gpg_req__ = {'Package': ['name', 'version']} + __gpg_ireq__ = {'Package': ['name', 'version']} + + __new_gpg_req__ = {'Package': ['name'], 'Instance': ['version', 'release']} + __new_gpg_ireq__ = {'Package': ['name'], 'Instance': ['version', 'release']} + + conflicts = ['RPMng'] + + def Install(self, packages): + ''' + Try and fix everything that RPMng.VerifyPackages() found wrong for + each Package Entry. This can result in individual RPMs being + installed (for the first time), deleted, downgraded + or upgraded. + + NOTE: YUM can not reinstall a package that it thinks is already + installed. + + packages is a list of Package Elements that has + self.states[<Package Element>] == False + + The following effects occur: + - self.states{} is conditionally updated for each package. + - self.installed{} is rebuilt, possibly multiple times. + - self.instance_status{} is conditionally updated for each instance + of a package. + - Each package will be added to self.modified[] if its self.states{} + entry is set to True. + ''' + self.logger.info('Runing YUMng.Install()') + + install_pkgs = [] + gpg_keys = [] + upgrade_pkgs = [] + + # Remove extra instances. + # Can not reverify because we don't have a package entry. + if len(self.extra_instances) > 0: + self.RemovePackages(self.extra_instances) + + # Figure out which instances of the packages actually need something + # doing to them and place in the appropriate work 'queue'. + for pkg in packages: + for inst in [inst for inst in pkg if inst.tag == 'Instance' or inst.tag == 'Package']: + if self.instance_status[inst].get('installed', False) == False: + if pkg.get('name') == 'gpg-pubkey': + gpg_keys.append(inst) + else: + install_pkgs.append(inst) + elif self.instance_status[inst].get('version_fail', False) == True: + upgrade_pkgs.append(inst) + + # Install GPG keys. + # Alternatively specify the required keys using 'gpgkey' in the + # repository definition in yum.conf. YUM will install the keys + # automatically. + if len(gpg_keys) > 0: + for inst in gpg_keys: + self.logger.info("Installing GPG keys.") + key_arg = os.path.join(self.instance_status[inst].get('pkg').get('uri'), \ + inst.get('simplefile')) + cmdrc, output = self.cmd.run("rpm --import %s" % key_arg) + if cmdrc != 0: + self.logger.debug("Unable to install %s-%s" % \ + (self.instance_status[inst].get('pkg').get('name'), \ + self.str_evra(inst))) + else: + self.logger.debug("Installed %s-%s-%s" % \ + (self.instance_status[inst].get('pkg').get('name'), \ + inst.get('version'), inst.get('release'))) + self.RefreshPackages() + self.gpg_keyids = self.getinstalledgpg() + pkg = self.instance_status[gpg_keys[0]].get('pkg') + self.states[pkg] = self.VerifyPackage(pkg, []) + + # Install packages. + if len(install_pkgs) > 0: + self.logger.info("Attempting to install packages") + + if YAD: + pkgtool = "/usr/bin/yum -d0 -y install %s" + else: + pkgtool = "/usr/bin/yum -d0 install %s" + + install_args = [] + for inst in install_pkgs: + pkg_arg = self.instance_status[inst].get('pkg').get('name') + '-' + if inst.get('epoch', False): + pkg_arg = pkg_arg + inst.get('epoch') + ':' + pkg_arg = pkg_arg + inst.get('version') + '-' + inst.get('release') + if inst.get('arch', False): + pkg_arg = pkg_arg + '.' + inst.get('arch') + install_args.append(pkg_arg) + + cmdrc, output = self.cmd.run(pkgtool % " ".join(install_args)) + if cmdrc == 0: + # The yum command succeeded. All packages installed. + self.logger.info("Single Pass for Install Succeded") + self.RefreshPackages() + + # Reverify all the packages that we might have just changed. + # There may be multiple instances per package, only do the + # verification once. + install_pkg_set = set([self.instance_status[inst].get('pkg') \ + for inst in install_pkgs]) + self.logger.info("Reverifying Installed Packages") + for inst in install_pkgs: + pkg_entry = self.instance_status[inst].get('pkg') + if pkg_entry in install_pkg_set: + self.logger.debug("Reverifying Installed %s" % \ + (pkg_entry.get('name'))) + install_pkg_set.remove(pkg_entry) + self.states[pkg_entry] = self.VerifyPackage(pkg_entry, \ + self.instance_status[inst].get('modlist')) + else: + # We already reverified this pacakge. + continue + else: + # The yum command failed. No packages installed. + # Try installing instances individually. + self.logger.error("Single Pass Install of Packages Failed") + installed_instances = [] + for inst in install_pkgs: + pkg_arg = self.instance_status[inst].get('pkg').get('name') + '-' + if inst.get('epoch', False): + pkg_arg = pkg_arg + inst.get('epoch') + ':' + pkg_arg = pkg_arg + inst.get('version') + '-' + inst.get('release') + if inst.get('arch', False): + pkg_arg = pkg_arg + '.' + inst.get('arch') + cmdrc, output = self.cmd.run(pkgtool % pkg_arg) + if cmdrc == 0: + installed_instances.append(inst) + else: + self.logger.debug("%s %s would not install." % \ + (self.instance_status[inst].get('pkg').get('name'), \ + self.str_evra(inst))) + + install_pkg_set = set([self.instance_status[inst].get('pkg') \ + for inst in install_pkgs]) + self.RefreshPackages() + for inst in installed_instances: + pkg = inst.get('pkg') + # Reverify all the packages that we might have just changed. + # There may be multiple instances per package, only do the + # verification once. + if pkg in install_pkg_set: + self.logger.debug("Reverifying Installed Package %s" % \ + (pkg_entry.get('name'))) + install_pkg_set.remove(pkg) + self.states[pkg_entry] = self.VerifyPackage(pkg, \ + self.instance_status[inst].get('modlist')) + else: + # We already reverified this pacakge. + continue + + # Fix upgradeable packages. + if len(upgrade_pkgs) > 0: + self.logger.info("Attempting to upgrade packages") + + if YAD: + pkgtool = "/usr/bin/yum -d0 -y update %s" + else: + pkgtool = "/usr/bin/yum -d0 update %s" + + upgrade_args = [] + for inst in upgrade_pkgs: + pkg_arg = self.instance_status[inst].get('pkg').get('name') + '-' + if inst.haskey('epoch'): + pkg_arg = pkg_arg + inst.get('epoch') + ':' + pkg_arg = pkg_arg + inst.get('version') + '-' + inst.get('release') + if inst.haskey('arch'): + pkg_arg = pkg_arg + '.' + inst.get('arch') + upgrade_args.append(pkg_arg) + + cmdrc, output = self.cmd.run(pkgtool % " ".join(upgrade_args)) + if cmdrc == 0: + # The yum command succeeded. All packages installed. + self.logger.info("Single Pass for Install Succeded") + self.RefreshPackages() + + # Reverify all the packages that we might have just changed. + # There may be multiple instances per package, only do the + # verification once. + install_pkg_set = set([self.instance_status[inst].get('pkg') \ + for inst in upgrade_pkgs]) + self.logger.info("Reverifying Installed Packages") + for inst in upgrade_pkgs: + pkg_entry = self.instance_status[inst].get('pkg') + if pkg_entry in install_pkg_set: + self.logger.debug("Reverifying Installed %s" % \ + (pkg_entry.get('name'))) + install_pkg_set.remove(pkg_entry) + self.states[pkg_entry] = self.VerifyPackage(pkg_entry, \ + self.instance_status[inst].get('modlist')) + else: + # We already reverified this pacakge. + continue + else: + # The yum command failed. No packages installed. + # Try installing instances individually. + self.logger.error("Single Pass Install of Packages Failed") + installed_instances = [] + for inst in upgrade_pkgs: + pkg_arg = self.instance_status[inst].get('pkg').get('name') + '-' + if inst.haskey('epoch'): + pkg_arg = pkg_arg + inst.get('epoch') + ':' + pkg_arg = pkg_arg + inst.get('version') + '-' + inst.get('release') + if inst.haskey('arch'): + pkg_arg = pkg_arg + '.' + inst.get('arch') + cmdrc, output = self.cmd.run(pkgtool % pkg_arg) + if cmdrc == 0: + installed_instances.append(inst) + else: + self.logger.debug("%s %s would not install." % \ + (self.instance_status[inst].get('pkg').get('name'), \ + self.str_evra(inst))) + + install_pkg_set = set([self.instance_status[inst].get('pkg') \ + for inst in upgrade_pkgs]) + self.RefreshPackages() + for inst in installed_instances: + pkg = inst.get('pkg') + # Reverify all the packages that we might have just changed. + # There may be multiple instances per package, only do the + # verification once. + if pkg in install_pkg_set: + self.logger.debug("Reverifying Installed Package %s" % \ + (pkg_entry.get('name'))) + install_pkg_set.remove(pkg) + self.states[pkg_entry] = self.VerifyPackage(pkg, \ + self.instance_status[inst].get('modlist')) + else: + # We already reverified this pacakge. + continue + + + for entry in [ent for ent in packages if self.states[ent]]: + self.modified.append(entry) + + def RemovePackages(self, packages): + ''' + Remove specified entries. + + packages is a list of Package Entries with Instances generated + by FindExtraPackages(). + ''' + self.logger.debug('Running YUMng.RemovePackages()') + + if YAD: + pkgtool = "/usr/bin/yum -d0 -y erase %s" + else: + pkgtool = "/usr/bin/yum -d0 erase %s" + + erase_args = [] + for pkg in packages: + for inst in pkg: + if pkg.get('name') != 'gpg-pubkey': + pkg_arg = pkg.get('name') + '-' + if inst.get('epoch', False): + pkg_arg = pkg_arg + inst.get('epoch') + ':' + pkg_arg = pkg_arg + inst.get('version') + '-' + inst.get('release') + if inst.get('arch', False): + pkg_arg = pkg_arg + '.' + inst.get('arch') + erase_args.append(pkg_arg) + else: + self.logger.info("WARNING: gpg-pubkey package not in configuration %s %s"\ + % (pkgspec.get('name'), self.str_evra(pkgspec))) + self.logger.info(" This package will be deleted in a future version of the RPMng driver.") + + cmdrc, output = self.cmd.run(pkgtool % " ".join(erase_args)) + if cmdrc == 0: + self.modified += packages + for pkg in erase_args: + self.logger.info("Deleted %s" % (pkg)) + else: + self.logger.info("Bulk erase failed with errors:") + self.logger.debug("Erase results = %s" % output) + self.logger.info("Attempting individual erase for each package.") + for pkg in packages: + pkg_modified = False + for inst in pkg: + if pkg.get('name') != 'gpg-pubkey': + pkg_arg = pkg.get('name') + '-' + if inst.haskey('epoch'): + pkg_arg = pkg_arg + inst.get('epoch') + ':' + pkg_arg = pkg_arg + inst.get('version') + '-' + inst.get('release') + if inst.haskey('arch'): + pkg_arg = pkg_arg + '.' + inst.get('arch') + else: + self.logger.info("WARNING: gpg-pubkey package not in configuration %s %s"\ + % (pkgspec.get('name'), self.str_evra(pkgspec))) + self.logger.info(" This package will be deleted in a future version of the RPMng driver.") + + cmdrc, output = self.cmd.run(self.pkgtool % pkg_arg) + if cmdrc == 0: + pkg_modified = True + self.logger.info("Deleted %s" % pkg_arg) + else: + self.logger.error("unable to delete %s" % pkg_arg) + self.logger.debug("Failure = %s" % output) + if pkg_modified == True: + self.modified.append(pkg) + + + self.RefreshPackages() + self.extra = self.FindExtraPackages() |