Changeset 3029
- Timestamp:
- 04/10/07 19:14:59 (3 years ago)
- Location:
- trunk/bcfg2/src/lib/Client/Tools
- Files:
-
- 2 modified
-
RPMng.py (modified) (19 diffs)
-
rpmtools.py (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/bcfg2/src/lib/Client/Tools/RPMng.py
r3013 r3029 3 3 __revision__ = '$Revision$' 4 4 5 import Bcfg2.Client.Tools, time, rpmtools, sys 5 import Bcfg2.Client.Tools, rpmtools, os.path, rpm, ConfigParser 6 6 7 7 8 class RPMng(Bcfg2.Client.Tools.PkgTool): … … 18 19 'Instance': ['simplefile', 'version', 'release', 'arch']} 19 20 20 __gpg_req__ = {'Package': ['name'], 'Instance': ['version', 'release']} 21 __gpg_ireq__ = {'Package': ['name'], 'Instance': ['version', 'release']} 21 __gpg_req__ = {'Package': ['name', 'version']} 22 __gpg_ireq__ = {'Package': ['name', 'version']} 23 24 __new_gpg_req__ = {'Package': ['name'], 'Instance': ['version', 'release']} 25 __new_gpg_ireq__ = {'Package': ['name'], 'Instance': ['version', 'release']} 22 26 23 27 conflicts = ['RPM'] … … 26 30 pkgtool = ("rpm --oldpackage --replacepkgs --quiet -U %s", ("%s", ["url"])) 27 31 28 # This is mostly the default list from YUM on Centos 4. Check these are29 # still correct.30 # ***** Should probably put in bcfg2.config somewhere. *****31 installOnlyPkgs = ['kernel', 'kernel-bigmem', 'kernel-enterprise', 'kernel-smp',32 'kernel-modules', 'kernel-debug', 'kernel-unsupported',33 'kernel-source', 'kernel-devel', 'kernel-default',34 'kernel-largesmp-devel', 'kernel-largesmp', 'gpg-pubkey']35 32 36 33 def __init__(self, logger, setup, config, states): 37 34 Bcfg2.Client.Tools.PkgTool.__init__(self, logger, setup, config, states) 38 35 36 self.installOnlyPkgs = [] 37 self.erase_flags = [] 39 38 self.instance_status = {} 39 self.extra_instances = [] 40 self.gpg_keyids = self.getinstalledgpg() 41 42 # Process thee RPMng section from the config file. 43 RPMng_CP = ConfigParser.ConfigParser() 44 RPMng_CP.read(self.setup.get('setup')) 45 46 # installonlypackages 47 if RPMng_CP.has_option('RPMng','installonlypackages'): 48 self.installOnlyPkgs = RPMng_CP.get('RPMng','installonlypackages').split(',') + \ 49 ['gpg-pubkey'] 50 if self.installOnlyPkgs == []: 51 self.installOnlyPkgs = ['kernel', 'kernel-bigmem', 'kernel-enterprise', 'kernel-smp', 52 'kernel-modules', 'kernel-debug', 'kernel-unsupported', 53 'kernel-source', 'kernel-devel', 'kernel-default', 54 'kernel-largesmp-devel', 'kernel-largesmp', 'kernel-xen', 55 'gpg-pubkey'] 56 self.logger.debug('installOnlyPackages = %s' % self.installOnlyPkgs) 57 58 # erase_flags 59 if RPMng_CP.has_option('RPMng','erase_flags'): 60 self.installOnlyPkgs = RPMng_CP.get('RPMng','erase_flags').split(',') 61 if self.erase_flags == []: 62 self.erase_flags = ['allmatches'] 63 self.logger.debug('erase_flags = %s' % self.erase_flags) 40 64 41 65 def RefreshPackages(self): … … 57 81 self.installed = {} 58 82 refresh_ts = rpmtools.rpmtransactionset() 83 # Don't bother with signature checks at this stage. The GPG keys might 84 # not be installed. 85 refresh_ts.setVSFlags(rpm._RPMVSF_NODIGESTS|rpm._RPMVSF_NOSIGNATURES) 59 86 for nevra in rpmtools.rpmpackagelist(refresh_ts): 60 87 self.installed.setdefault(nevra['name'], []).append(nevra) … … 64 91 self.logger.info(" " + name) 65 92 for inst in instances: 66 self.logger.info(" %s:%s-%s.%s" % \ 67 (inst.get('epoch', None), inst.get('version', None), 68 inst.get('release', None), inst.get('arch', None))) 93 self.logger.info(" %s" %self.str_evra(inst)) 69 94 refresh_ts.closeDB() 95 del refresh_ts 70 96 71 97 def VerifyPackage(self, entry, modlist): 72 98 ''' 73 99 Verify Package status for entry. 74 Compares the 'version' info against self.installed{} and does 75 an rpm level package verify. 76 77 Code for the old/new style Package Entries has been kept separate, 78 even though it has meant some code duplication, so that the old style 79 code can be easily removed at a later date. 80 ''' 81 82 instances = entry.findall('Instance') 83 if not instances: 84 # We have an old style no Instance entry. 85 if entry.get('release', None) == None: 86 version, release = entry.get('version').split('-') 87 entry.set('version', version) 88 entry.set('release', release) 89 instances = [ entry ] 90 91 vp_ts = rpmtools.rpmtransactionset() 100 Performs the following: 101 - Checks for the presence of required Package Instances. 102 - Compares the evra 'version' info against self.installed{}. 103 - RPM level package verify (rpm --verify). 104 - Checks for the presence of unrequired package instances. 105 106 Produces the following dict and list for RPMng.Install() to use: 107 For installs/upgrades/fixes of required instances: 108 instance_status = { <Instance Element Object>: 109 { 'installed': True|False, 110 'version_fail': True|False, 111 'verify_fail': True|False, 112 'pkg': <Package Element Object>, 113 'modlist': [ <filename>, ... ], 114 'verify' : [ <rpm --verify results> ] 115 }, ...... 116 } 117 118 For deletions of unrequired instances: 119 extra_instances = [ <Package Element Object>, ..... ] 120 121 Constructs the text prompts for interactive mode. 122 ''' 123 if len(entry) == 0: 124 # We have an old style no Instance entry. Convert it to new style. 125 version, release = entry.get('version').split('-') 126 instance = Bcfg2.Client.XML.SubElement(entry, 'Package') 127 for attrib in entry.attrib.keys(): 128 instance.attrib[attrib] = entry.attrib[attrib] 129 instance.set('version', version) 130 instance.set('release', release) 131 instances = [ instance ] 132 else: 133 # We have a new style entry or a previously converted old style entry. 134 instances = [inst for inst in entry if inst.tag == 'Instance' or inst.tag == 'Package'] 92 135 93 136 self.logger.info("Verifying package instances for %s" % entry.get('name')) … … 105 148 self.instance_status[inst]['version_fail'] = False 106 149 if inst.tag == 'Package' and len(self.installed[entry.get('name')]) > 1: 107 self.logger.error("WARNING: Multiple instances of package %s are installed." % (entry.get('name'))) 150 self.logger.error("WARNING: Multiple instances of package %s are installed." % \ 151 (entry.get('name'))) 108 152 for pkg in self.installed[entry.get('name')]: 109 if inst.tag == 'Package': 110 # We have an old style Package entry that does not 111 # have an epoch or an arch, so scrub them from 112 # installed{}. 113 pkg.pop('arch', None) 114 pkg.pop('epoch', None) 115 if inst.get('epoch', None) != None: 116 epoch = int(inst.get('epoch')) 117 else: 118 epoch = None 119 if epoch == pkg.get('epoch') and \ 120 inst.get('version') == pkg.get('version') and \ 121 inst.get('release') == pkg.get('release') and \ 122 inst.get('arch', None) == pkg.get('arch', None): 123 self.logger.info(" %s:%s-%s.%s" % \ 124 (inst.get('epoch', None), inst.get('version'), 125 inst.get('release'), inst.get('arch', None))) 153 if self.pkg_vr_equal(inst, pkg) or self.inst_evra_equal(inst, pkg): 154 self.logger.info(" %s" % self.str_evra(inst)) 126 155 self.logger.debug(" verify_flags = %s" % \ 127 156 (inst.get('verify_flags', []))) 128 157 self.instance_status[inst]['installed'] = True 158 159 flags = inst.get('verify_flags', '').split(',') 160 if pkg.get('gpgkeyid', '')[-8:] not in self.gpg_keyids and \ 161 entry.get('name') != 'gpg-pubkey': 162 flags += ['nosignature', 'nodigest'] 163 self.logger.info('WARNING: Package %s %s requires GPG Public key with ID %s'\ 164 % (pkg.get('name'), self.str_evra(pkg), \ 165 pkg.get('gpgkeyid', ''))) 166 self.logger.info(' Disabling signature check.') 167 129 168 self.instance_status[inst]['verify'] = \ 130 rpmtools.rpm_verify( vp_ts, pkg, \ 131 inst.get('verify_flags', '').split(',')) 169 rpmtools.rpm_verify( self.vp_ts, pkg, flags) 132 170 133 171 if self.instance_status[inst]['installed'] == False: 134 package_fail = True 135 self.logger.info(" Package %s %s:%s-%s.%s not installed." % \ 136 (entry.get('name'), 137 inst.get('epoch', None), inst.get('version'), 138 inst.get('release'), inst.get('arch', None))) 172 self.logger.info(" Package %s %s not installed." % \ 173 (entry.get('name'), self.str_evra(inst))) 139 174 140 qtext_versions = qtext_versions + '%s:%s-%s.%s ' % \ 141 (inst.get('epoch', ''), inst.get('version', ''),\ 142 inst.get('release', ''), inst.get('arch', '')) 143 175 qtext_versions = qtext_versions + 'I(%s) ' % self.str_evra(inst) 144 176 entry.set('current_exists', 'false') 145 177 else: … … 164 196 # Check that it is the right version. 165 197 for pkg in arch_match: 166 if inst.tag == 'Package': 167 # We have an old style Package entry that does not 168 # have an epoch or an arch, so scrub them from 169 # installed{}. 170 pkg.pop('arch', None) 171 pkg.pop('epoch', None) 172 if inst.get('epoch', None) != None: 173 epoch = int(inst.get('epoch')) 174 else: 175 epoch = None 176 if epoch == pkg.get('epoch', None) and \ 177 inst.get('version') == pkg.get('version') and \ 178 inst.get('release') == pkg.get('release'): 179 self.logger.info(" %s:%s-%s.%s" % \ 180 (inst.get('epoch', None), inst.get('version', ''), \ 181 inst.get('release', ''), inst.get('arch', None))) 198 if self.pkg_vr_equal(inst, pkg) or self.inst_evra_equal(inst, pkg): 199 self.logger.info(" %s" % self.str_evra(inst)) 182 200 self.logger.debug(" verify_flags = %s" % \ 183 201 (inst.get('verify_flags', []))) 184 202 self.instance_status[inst]['installed'] = True 203 204 flags = inst.get('verify_flags', '').split(',') 205 if pkg.get('gpgkeyid', '')[-8:] not in self.gpg_keyids: 206 flags += ['nosignature', 'nodigest'] 207 self.logger.info('WARNING: Package %s %s requires GPG Public key with ID %s'\ 208 % (pkg.get('name'), self.str_evra(pkg), \ 209 pkg.get('gpgkeyid', ''))) 210 self.logger.info(' Disabling signature check.') 211 185 212 self.instance_status[inst]['verify'] = \ 186 rpmtools.rpm_verify( vp_ts, pkg,\187 inst.get('verify_flags', '').split(',')) 213 rpmtools.rpm_verify( self.vp_ts, pkg, flags ) 214 188 215 else: 189 package_fail = True216 # Wrong version installed. 190 217 self.instance_status[inst]['version_fail'] = True 191 self.logger.info(" Wrong version installed. Want %s:%s-%s.%s, but have %s:%s-%s.%s" % \ 192 (inst.get('epoch', None), inst.get('version'), \ 193 inst.get('release'), inst.get('arch', None), \ 194 pkg.get('epoch'), pkg.get('version'), \ 195 pkg.get('release'), pkg.get('arch'))) 218 self.logger.info(" Wrong version installed. Want %s, but have %s"\ 219 % (self.str_evra(inst), self.str_evra(pkg))) 196 220 197 qtext_versions = qtext_versions + \ 198 '(%s:%s-%s.%s -> %s:%s-%s.%s) ' % \ 199 (pkg.get('epoch', ''), pkg.get('version'), \ 200 pkg.get('release'), pkg.get('arch', ''), \ 201 inst.get('epoch', ''), inst.get('version'), \ 202 inst.get('release'), inst.get('arch', '')) 221 qtext_versions = qtext_versions + 'U(%s -> %s) ' % \ 222 (self.str_evra(pkg), self.str_evra(inst)) 203 223 elif len(arch_match) == 0: 204 224 # This instance is not installed. 205 225 self.instance_status[inst]['installed'] = False 206 207 self.logger.info(" %s:%s-%s.%s is not installed." % \ 208 (inst.get('epoch', None), inst.get('version'), \ 209 inst.get('release'), inst.get('arch', None))) 210 211 qtext_versions = qtext_versions + '%s:%s-%s.%s ' % \ 212 (inst.get('epoch', ''), inst.get('version'), \ 213 inst.get('release'), inst.get('arch', '')) 214 215 entry.set('current_exists', 'false') 216 226 self.logger.info(" %s is not installed." % self.str_evra(inst)) 227 qtext_versions = qtext_versions + 'I(%s) ' % self.str_evra(inst) 228 229 # Check the rpm verify results. 217 230 for inst in instances: 218 231 instance_fail = False … … 222 235 self.logger.debug(self.instance_status[inst]['verify']) 223 236 224 # Check the rpm verify results.237 self.instance_status[inst]['verify_fail'] = False 225 238 if self.instance_status[inst].get('verify', None): 226 239 if len(self.instance_status[inst].get('verify')) > 1: 227 240 self.logger.info("WARNING: Verification of more than one package instance.") 228 241 229 self.instance_status[inst]['verify_fail'] = False230 242 231 243 for result in self.instance_status[inst]['verify']: 232 244 233 245 # Check header results 234 if result.get('hdr', []): 235 package_fail = True 246 if result.get('hdr', None): 236 247 instance_fail = True 237 248 self.instance_status[inst]['verify_fail'] = True 238 249 239 250 # Check dependency results 240 if result.get('deps', []): 241 package_fail = True 251 if result.get('deps', None): 242 252 instance_fail = True 243 253 self.instance_status[inst]['verify_fail'] = True … … 249 259 file_result[-1] not in \ 250 260 [ignore.get('name') for ignore in inst.findall('Ignore')]: 251 package_fail = True252 261 instance_fail = True 253 262 self.instance_status[inst]['verify_fail'] = True … … 257 266 258 267 if instance_fail == True: 259 self.logger.info("*** Instance %s:%s-%s.%s failed RPM verification ***" % \ 260 (inst.get('epoch', None), inst.get('version'), \ 261 inst.get('release'), inst.get('arch', None))) 262 263 qtext_versions = qtext_versions + '%s:%s-%s.%s ' % \ 264 (inst.get('epoch', ''), inst.get('version'), \ 265 inst.get('release'), inst.get('arch', '')) 268 self.logger.info("*** Instance %s failed RPM verification ***" % \ 269 self.str_evra(inst)) 270 qtext_versions = qtext_versions + 'R(%s) ' % self.str_evra(inst) 271 self.instance_status[inst]['modlist'] = modlist 266 272 267 273 if self.instance_status[inst]['installed'] == False or \ 268 self.instance_status[inst]['version_fail'] == True: 274 self.instance_status[inst].get('version_fail', False)== True or \ 275 self.instance_status[inst].get('verify_fail', False) == True: 269 276 package_fail = True 270 277 self.instance_status[inst]['pkg'] = entry 278 self.instance_status[inst]['modlist'] = modlist 279 280 # Find Installed Instances that are not in the Config. 281 extra_installed = self.FindExtraInstances(entry, self.installed[entry.get('name')]) 282 if extra_installed != None: 283 package_fail = True 284 self.extra_instances.append(extra_installed) 285 for inst in extra_installed.findall('Instance'): 286 qtext_versions = qtext_versions + 'D(%s) ' % self.str_evra(inst) 287 self.logger.debug("Found Extra Instances %s" % qtext_versions) 288 271 289 if package_fail == True: 272 self.logger.info(" Package %s failed verification." % \ 273 (entry.get('name'))) 274 qtext = 'Upgrade/downgrade Package %s instance(s) - %s (y/N) ' % \ 290 self.logger.info(" Package %s failed verification." % (entry.get('name'))) 291 qtext = 'Install/Upgrade/delete Package %s instance(s) - %s (y/N) ' % \ 275 292 (entry.get('name'), qtext_versions) 276 293 entry.set('qtext', qtext) 277 entry.set('current_version', "%s:%s-%s.%s" % \ 278 (inst.get('epoch', None), inst.get('version'), 279 inst.get('release'), inst.get('arch', None))) 294 295 bcfg2_versions = '' 296 for bcfg2_inst in [inst for inst in instances if inst.tag == 'Instance']: 297 bcfg2_versions = bcfg2_versions + '(%s) ' % self.str_evra(bcfg2_inst) 298 if bcfg2_versions != '': 299 entry.set('version', bcfg2_versions) 300 installed_versions = '' 301 302 for installed_inst in self.installed[entry.get('name')]: 303 installed_versions = installed_versions + '(%s) ' % \ 304 self.str_evra(installed_inst) 305 306 entry.set('current_version', installed_versions) 280 307 return False 281 308 … … 284 311 self.logger.debug("Package %s has no instances installed" % (entry.get('name'))) 285 312 entry.set('current_exists', 'false') 313 bcfg2_versions = '' 286 314 for inst in instances: 287 qtext_versions = qtext_versions + '%s:%s-%s.%s ' % \ 288 (inst.get('epoch', None), inst.get('version'), 289 inst.get('release'), inst.get('arch', None)) 315 qtext_versions = qtext_versions + 'I(%s) ' % self.str_evra(inst) 290 316 self.instance_status.setdefault(inst, {})['installed'] = False 291 317 self.instance_status[inst]['modlist'] = modlist 318 self.instance_status[inst]['pkg'] = entry 319 if inst.tag == 'Instance': 320 bcfg2_versions = bcfg2_versions + '(%s) ' % self.str_evra(inst) 321 if bcfg2_versions != '': 322 entry.set('version', bcfg2_versions) 292 323 entry.set('qtext', "Install Package %s Instance(s) %s? (y/N) " % \ 293 324 (entry.get('name'), qtext_versions)) 294 325 295 326 return False 296 327 return True 297 328 298 329 def RemovePackages(self, packages): 299 '''Remove specified entries''' 300 #pkgnames = [pkg.get('name') for pkg in packages] 301 #if len(pkgnames) > 0: 302 # self.logger.info("Removing packages: %s" % pkgnames) 303 # if self.cmd.run("rpm --quiet -e --allmatches %s" % " ".join(pkgnames))[0] == 0: 304 # self.modified += packages 305 # else: 306 # for pkg in packages: 307 # if self.cmd.run("rpm --quiet -e --allmatches %s" % \ 308 # pkg.get('name'))[0] == 0: 309 # self.modified += pkg 310 # 311 # self.RefreshPackages() 312 # self.extra = self.FindExtraPackages() 313 print "The following package instances would have been deleted:" 330 ''' 331 Remove specified entries. 332 333 packages is a list of Package Entries with Instances generated 334 by FindExtraPackages(). 335 ''' 336 self.logger.debug('Running RPMng.RemovePackages()') 337 338 pkgspec_list = [] 314 339 for pkg in packages: 315 print " %s:" % (pkg.get('name'))316 340 for inst in pkg: 317 print " %s:%s-%s.%s" % (inst.get('epoch', None), inst.get('version'), \ 318 inst.get('release'), inst.get('arch', None)) 319 341 if pkg.get('name') != 'gpg-pubkey': 342 pkgspec = { 'name':pkg.get('name'), 343 'epoch':inst.get('epoch', None), 344 'version':inst.get('version'), 345 'release':inst.get('release'), 346 'arch':inst.get('arch') } 347 pkgspec_list.append(pkgspec) 348 else: 349 pkgspec = { 'name':pkg.get('name'), 350 'version':inst.get('version'), 351 'release':inst.get('release')} 352 self.logger.info("WARNING: gpg-pubkey package not in configuration %s %s"\ 353 % (pkgspec.get('name'), self.str_evra(pkgspec))) 354 self.logger.info(" This package will be deleted in a future version of the RPMng driver.") 355 #pkgspec_list.append(pkg_spec) 356 357 erase_results = rpmtools.rpm_erase(pkgspec_list, self.erase_flags) 358 if erase_results == []: 359 self.modified += packages 360 for pkg in pkgspec_list: 361 self.logger.info("Deleted %s %s" % (pkg.get('name'), self.str_evra(pkg))) 362 else: 363 self.logger.info("Bulk erase failed with errors:") 364 self.logger.debug("Erase results = %s" % erase_results) 365 self.logger.info("Attempting individual erase for each package.") 366 pkgspec_list = [] 367 for pkg in packages: 368 pkg_modified = False 369 for inst in pkg: 370 if pkg.get('name') != 'gpg-pubkey': 371 pkgspec = { 'name':pkg.get('name'), 372 'epoch':inst.get('epoch', None), 373 'version':inst.get('version'), 374 'release':inst.get('release'), 375 'arch':inst.get('arch') } 376 pkgspec_list.append(pkgspec) 377 else: 378 pkgspec = { 'name':pkg.get('name'), 379 'version':inst.get('version'), 380 'release':inst.get('release')} 381 self.logger.info("WARNING: gpg-pubkey package not in configuration %s %s"\ 382 % (pkgspec.get('name'), self.str_evra(pkgspec))) 383 self.logger.info(" This package will be deleted in a future version of the RPMng driver.") 384 continue # Don't delete the gpg-pubkey packages for now. 385 erase_results = rpmtools.rpm_erase([pkgspec], self.erase_flags) 386 if erase_results == []: 387 pkg_modified = True 388 self.logger.info("Deleted %s %s" % \ 389 (pkgspec.get('name'), self.str_evra(pkgspec))) 390 else: 391 self.logger.error("unable to delete %s %s" % \ 392 (pkgspec.get('name'), self.str_evra(pkgspec))) 393 self.logger.debug("Failure = %s" % erase_results) 394 if pkg_modified == True: 395 self.modified.append(pkg) 396 397 self.RefreshPackages() 398 self.extra = self.FindExtraPackages() 399 400 def reinstall_check(self, verify_results): 401 ''' 402 Control if a reinstall of a package happens or not based on the 403 results from RPMng.VerifyPackage(). 404 405 Return True to reinstall, False to not reintstall. 406 ''' 407 reinstall = False 408 409 for inst in verify_results.get('verify'): 410 self.logger.debug('reinstall_check: %s %s:%s-%s.%s' % inst.get('nevra')) 411 412 # Parse file results 413 for file_result in inst.get('files'): 414 self.logger.debug('reinstall_check: file: %s' % file_result) 415 if file_result[-2] != 'c': 416 reinstall = True 417 418 return reinstall 419 320 420 def Install(self, packages): 321 421 ''' 322 ''' 323 self.logger.info('''The following packages have something wrong with them and RPM.Install() 324 will try and do something to fix them if appropriate:''') 325 422 Try and fix everything that RPMng.VerifyPackages() found wrong for 423 each Package Entry. This can result in individual RPMs being 424 installed (for the first time), reinstalled, deleted, downgraded 425 or upgraded. 426 427 packages is a list of Package Elements that has 428 self.states[<Package Element>] == False 429 430 The following effects occur: 431 - self.states{} is conditionally updated for each package. 432 - self.installed{} is rebuilt, possibly multiple times. 433 - self.instance_statusi{} is conditionally updated for each instance 434 of a package. 435 - Each package will be added to self.modified[] if its self.states{} 436 entry is set to True. 437 ''' 438 self.logger.info('Runing RPMng.Install()') 439 440 install_only_pkgs = [] 441 gpg_keys = [] 442 upgrade_pkgs = [] 443 444 # Remove extra instances. 445 # Can not reverify because we don't have a package entry. 446 if len(self.extra_instances) > 0: 447 self.RemovePackages(self.extra_instances) 448 449 # Figure out which instances of the packages actually need something 450 # doing to them and place in the appropriate work 'queue'. 326 451 for pkg in packages: 327 instances = pkg.findall('Instance') 328 if not instances: 329 instances = [ pkg ] 330 for inst in instances: 452 for inst in [inst for inst in pkg if inst.tag == 'Instance' or inst.tag == 'Package']: 331 453 if self.instance_status[inst].get('installed', False) == False or \ 332 454 self.instance_status[inst].get('version_fail', False) == True or \ 333 self.instance_status[inst].get('verify_fail', False) == True: 334 print "%s: %s:%s-%s.%s installed = %s, Version_fail = %s, verify_fail = %s" % \ 335 (pkg.get('name'),inst.get('epoch', None), inst.get('version'), \ 336 inst.get('release'), inst.get('arch', None), \ 337 self.instance_status[inst].get('installed', None),\ 338 self.instance_status[inst].get('version_fail', None),\ 339 self.instance_status[inst].get('verify_fail', None)) 455 (self.instance_status[inst].get('verify_fail', False) == True and \ 456 self.reinstall_check(self.instance_status[inst])): 457 if pkg.get('name') == 'gpg-pubkey': 458 gpg_keys.append(inst) 459 elif pkg.get('name') in self.installOnlyPkgs: 460 install_only_pkgs.append(inst) 461 else: 462 upgrade_pkgs.append(inst) 463 464 # Fix installOnlyPackages 465 if len(install_only_pkgs) > 0: 466 self.logger.info("Attempting to install 'install only packages'") 467 install_args = " ".join([os.path.join(self.instance_status[inst].get('pkg').get('uri'), \ 468 inst.get('simplefile')) \ 469 for inst in install_only_pkgs]) 470 self.logger.debug("rpm --install --quiet --oldpackage %s" % install_args) 471 cmdrc, output = self.cmd.run("rpm --install --quiet --oldpackage --replacepkgs %s" % \ 472 install_args) 473 if cmdrc == 0: 474 # The rpm command succeeded. All packages installed. 475 self.logger.info("Single Pass for InstallOnlyPkgs Succeded") 476 self.RefreshPackages() 477 478 # Reverify all the packages that we might have just changed. 479 # There may be multiple instances per package, only do the 480 # verification once. 481 install_pkg_set = set([self.instance_status[inst].get('pkg') \ 482 for inst in install_only_pkgs]) 483 self.logger.info("Reverifying InstallOnlyPkgs") 484 for inst in install_only_pkgs: 485 pkg_entry = self.instance_status[inst].get('pkg') 486 if pkg_entry in install_pkg_set: 487 self.logger.debug("Reverifying InstallOnlyPkg %s" % \ 488 (pkg_entry.get('name'))) 489 install_pkg_set.remove(pkg_entry) 490 self.states[pkg_entry] = self.VerifyPackage(pkg_entry, \ 491 self.instance_status[inst].get('modlist')) 492 else: 493 # We already reverified this pacakge. 494 continue 495 else: 496 # The rpm command failed. No packages installed. 497 # Try installing instances individually. 498 self.logger.error("Single Pass for InstallOnlyPackages Failed") 499 installed_instances = [] 500 for inst in install_only_pkgs: 501 install_args = os.path.join(self.instance_status[inst].get('pkg').get('uri'), \ 502 inst.get('simplefile')) 503 self.logger.debug("rpm --install --quiet --oldpackage %s" % install_args) 504 cmdrc, output = self.cmd.run("rpm --install --quiet --oldpackage --replacepkgs %s" % \ 505 install_args) 506 if cmdrc == 0: 507 installed_instances.append(inst) 508 else: 509 self.logger.debug("InstallOnlyPackage %s %s would not install." % \ 510 (self.instance_status[inst].get('pkg').get('name'),\ 511 self.str_evra(inst))) 512 513 install_pkg_set = set([self.instance_status[inst].get('pkg') \ 514 for inst in install_only_pkgs]) 515 self.RefreshPackages() 516 for inst in installed_instances: 517 pkg = inst.get('pkg') 518 # Reverify all the packages that we might have just changed. 519 # There may be multiple instances per package, only do the 520 # verification once. 521 if pkg in install_pkg_set: 522 self.logger.debug("Reverifying InstallOnlyPkg %s" % \ 523 (pkg_entry.get('name'))) 524 install_pkg_set.remove(pkg) 525 self.states[pkg_entry] = self.VerifyPackage(pkg, \ 526 self.instance_status[inst].get('modlist')) 527 else: 528 # We already reverified this pacakge. 529 continue 530 531 # Install GPG keys. 532 if len(gpg_keys) > 0: 533 for inst in gpg_keys: 534 self.logger.info("Installing GPG keys.") 535 key_arg = os.path.join(self.instance_status[inst].get('pkg').get('uri'), \ 536 inst.get('simplefile')) 537 cmdrc, output = self.cmd.run("rpm --import %s" % key_arg) 538 if cmdrc != 0: 539 self.logger.debug("Unable to install %s-%s" % \ 540 (self.instance_status[inst].get('pkg').get('name'), \ 541 self.str_evra(inst))) 542 else: 543 self.logger.debug("Installed %s-%s-%s" % \ 544 (self.instance_status[inst].get('pkg').get('name'), \ 545 inst.get('version'), inst.get('release'))) 546 self.RefreshPackages() 547 self.gpg_keyids = self.getinstalledgpg() 548 pkg = self.instance_status[gpg_keys[0]].get('pkg') 549 self.states[pkg] = self.VerifyPackage(pkg, []) 550 551 # Fix upgradeable packages. 552 if len(upgrade_pkgs) > 0: 553 self.logger.info("Attempting to upgrade packages") 554 upgrade_args = " ".join([os.path.join(self.instance_status[inst].get('pkg').get('uri'), \ 555 inst.get('simplefile')) \ 556 for inst in upgrade_pkgs]) 557 cmdrc, output = self.cmd.run("rpm --upgrade --quiet --oldpackage --replacepkgs %s" % \ 558 upgrade_args) 559 if cmdrc == 0: 560 # The rpm command succeeded. All packages upgraded. 561 self.logger.info("Single Pass for Upgraded Packages Succeded") 562 upgrade_pkg_set = set([self.instance_status[inst].get('pkg') \ 563 for inst in upgrade_pkgs]) 564 self.RefreshPackages() 565 for inst in upgrade_pkgs: 566 pkg_entry = self.instance_status[inst].get('pkg') 567 # Reverify all the packages that we might have just changed. 568 # There may be multiple instances per package, only do the 569 # verification once. 570 if pkg_entry in upgrade_pkg_set: 571 self.logger.debug("Reverifying Upgradable Package %s" % \ 572 (pkg_entry.get('name'))) 573 upgrade_pkg_set.remove(pkg_entry) 574 self.states[pkg_entry] = self.VerifyPackage(pkg_entry, 575 self.instance_status[inst].get('modlist')) 576 else: 577 # We already reverified this pacakge. 578 continue 579 else: 580 # The rpm command failed. No packages upgraded. 581 # Try upgrading instances individually. 582 self.logger.error("Single Pass for Upgrading Packages Failed") 583 upgraded_instances = [] 584 for inst in upgrade_pkgs: 585 upgrade_args = os.path.join(self.instance_status[inst].get('pkg').get('uri'), \ 586 inst.get('simplefile')) 587 #self.logger.debug("rpm --upgrade --quiet --oldpackage --replacepkgs %s" % \ 588 # upgrade_args) 589 cmdrc, output = self.cmd.run("rpm --upgrade --quiet --oldpackage --replacepkgs %s" % upgrade_args) 590 if cmdrc == 0: 591 upgraded_instances.append(inst) 592 else: 593 self.logger.debug("Package %s %s would not upgrade." % \ 594 (self.instance_status[inst].get('pkg').get('name'),\ 595 self.str_evra(inst))) 596 597 upgrade_pkg_set = set([self.instance_status[inst].get('pkg') \ 598 for inst in upgrade_pkgs]) 599 self.RefreshPackages() 600 for inst in upgraded_instances: 601 pkg_entry = self.instance_status[inst].get('pkg') 602 # Reverify all the packages that we might have just changed. 603 # There may be multiple instances per package, only do the 604 # verification once. 605 if pkg_entry in upgrade_pkg_set: 606 self.logger.debug("Reverifying Upgradable Package %s" % \ 607 (pkg_entry.get('name'))) 608 upgrade_pkg_set.remove(pkg_entry) 609 self.states[pkg_entry] = self.VerifyPackage(pkg_entry, \ 610 self.instance_status[inst].get('modlist')) 611 else: 612 # We already reverified this pacakge. 613 continue 614 615 for entry in [ent for ent in packages if self.states[ent]]: 616 self.modified.append(entry) 340 617 341 618 def canInstall(self, entry): … … 349 626 350 627 if not instances: 351 # Old non Instance format. 352 if [attr for attr in self.__ireq__[entry.tag] if attr not in entry.attrib]: 353 self.logger.error("Incomplete information for entry %s:%s; cannot verify" \ 354 % (entry.tag, entry.get('name'))) 355 return False 628 # Old non Instance format, unmodified. 629 if entry.get('name') == 'gpg-pubkey': 630 # gpg-pubkey packages aren't really pacakges, so we have to do 631 # something a little different. 632 # Check that the Package Level has what we need for verification. 633 if [attr for attr in self.__gpg_ireq__[entry.tag] if attr not in entry.attrib]: 634 self.logger.error("Incomplete information for entry %s:%s; cannot install" \ 635 % (entry.tag, entry.get('name'))) 636 return False 637 else: 638 if [attr for attr in self.__ireq__[entry.tag] if attr not in entry.attrib]: 639 self.logger.error("Incomplete information for entry %s:%s; cannot install" \ 640 % (entry.tag, entry.get('name'))) 641 return False 356 642 else: 357 643 if entry.get('name') == 'gpg-pubkey': … … 359 645 # something a little different. 360 646 # Check that the Package Level has what we need for verification. 361 if [attr for attr in self.__ gpg_ireq__[entry.tag] if attr not in entry.attrib]:362 self.logger.error("Incomplete information for entry %s:%s; cannot verify" \647 if [attr for attr in self.__new_gpg_ireq__[entry.tag] if attr not in entry.attrib]: 648 self.logger.error("Incomplete information for entry %s:%s; cannot install" \ 363 649 % (entry.tag, entry.get('name'))) 364 650 return False 365 651 # Check that the Instance Level has what we need for verification. 366 652 for inst in instances: 367 if [attr for attr in self.__gpg_ireq__[inst.tag] if attr not in inst.attrib]: 368 self.logger.error("Incomplete information for entry %s:%s; cannot verify" \ 653 if [attr for attr in self.__new_gpg_ireq__[inst.tag] \ 654 if attr not in inst.attrib]: 655 self.logger.error("Incomplete information for entry %s:%s; cannot install"\ 369 656 % (inst.tag, inst.get('name'))) 370 657 return False … … 373 660 # Check that the Package Level has what we need for verification. 374 661 if [attr for attr in self.__new_ireq__[entry.tag] if attr not in entry.attrib]: 375 self.logger.error("Incomplete information for entry %s:%s; cannot verify" \662 self.logger.error("Incomplete information for entry %s:%s; cannot install" \ 376 663 % (entry.tag, entry.get('name'))) 377 664 return False 378 665 # Check that the Instance Level has what we need for verification. 379 666 for inst in instances: 380 if [attr for attr in self.__new_ireq__[inst.tag] if attr not in inst.attrib]: 381 self.logger.error("Incomplete information for entry %s:%s; cannot verify" \ 382 % (inst.tag, inst.get('name'))) 383 return False 667 if inst.tag == 'Instance': 668 if [attr for attr in self.__new_ireq__[inst.tag] \ 669 if attr not in inst.attrib]: 670 self.logger.error("Incomplete information for entry %s:%s; cannot install" \ 671 % (inst.tag, inst.get('name'))) 672 return False 384 673 return True 385 674 … … 392 681 New style Package with Instances 393 682 pgp-pubkey packages 683 684 Also the old style entries get modified after the first 685 VerifyPackage() run, so there needs to be a second test. 394 686 ''' 395 687 if not self.handlesEntry(entry): … … 399 691 400 692 if not instances: 401 # Old non Instance format. 402 if [attr for attr in self.__req__[entry.tag] if attr not in entry.attrib]: 403 self.logger.error("Incomplete information for entry %s:%s; cannot verify" \ 404 % (entry.tag, entry.get('name'))) 405 return False 406 else: 693 # Old non Instance format, unmodified. 407 694 if entry.get('name') == 'gpg-pubkey': 408 695 # gpg-pubkey packages aren't really pacakges, so we have to do … … 413 700 % (entry.tag, entry.get('name'))) 414 701 return False 702 else: 703 if [attr for attr in self.__req__[entry.tag] if attr not in entry.attrib]: 704 self.logger.error("Incomplete information for entry %s:%s; cannot verify" \ 705 % (entry.tag, entry.get('name'))) 706 return False 707 else: 708 if entry.get('name') == 'gpg-pubkey': 709 # gpg-pubkey packages aren't really pacakges, so we have to do 710 # something a little different. 711 # Check that the Package Level has what we need for verification. 712 if [attr for attr in self.__new_gpg_req__[entry.tag] if attr not in entry.attrib]: 713 self.logger.error("Incomplete information for entry %s:%s; cannot verify" \ 714 % (entry.tag, entry.get('name'))) 715 return False 415 716 # Check that the Instance Level has what we need for verification. 416 717 for inst in instances: 417 if [attr for attr in self.__gpg_req__[inst.tag] if attr not in inst.attrib]: 718 if [attr for attr in self.__new_gpg_req__[inst.tag] \ 719 if attr not in inst.attrib]: 418 720 self.logger.error("Incomplete information for entry %s:%s; cannot verify" \ 419 721 % (inst.tag, inst.get('name'))) 420 722 return False 421 723 else: 422 # New format with Instances .724 # New format with Instances, or old style modified. 423 725 # Check that the Package Level has what we need for verification. 424 726 if [attr for attr in self.__new_req__[entry.tag] if attr not in entry.attrib]: … … 428 730 # Check that the Instance Level has what we need for verification. 429 731 for inst in instances: 430 if [attr for attr in self.__new_req__[inst.tag] if attr not in inst.attrib]: 431 self.logger.error("Incomplete information for entry %s:%s; cannot verify" \ 432 % (inst.tag, inst.get('name'))) 433 return False 732 if inst.tag == 'Instance': 733 if [attr for attr in self.__new_req__[inst.tag] \ 734 if attr not in inst.attrib]: 735 self.logger.error("Incomplete information for entry %s:%s; cannot verify" \ 736 % (inst.tag, inst.get('name'))) 737 return False 434 738 return True 435 739 … … 438 742 Find extra packages 439 743 ''' 440 extra_packages = [] 441 packages = {} 442 for entry in self.getSupportedEntries(): 443 packages[entry.get('name')] = entry 444 445 for name, pkg_list in self.installed.iteritems(): 446 extra_entry = Bcfg2.Client.XML.Element('Package', name=name, type=self.pkgtype) 447 if packages.get(name, None) != None: 448 # There is supposed to be at least one instance installed. 449 instances = packages[name].findall('Instance') 450 if not instances: 451 instances = [ packages[name] ] 452 if name in self.installOnlyPkgs: 453 for installed_inst in pkg_list: 454 not_found = True 455 for inst in instances: 456 if inst.get('epoch', None) != None: 457 epoch = int(inst.get('epoch')) 458 else: 459 epoch = None 460 if epoch == installed_inst.get('epoch') and \ 461 inst.get('version') == installed_inst.get('version') and \ 462 inst.get('release') == installed_inst.get('release') and \ 463 inst.get('arch', None) == installed_inst.get('arch'): 464 not_found = False 465 break 466 if not_found == True: 467 # Extra package. 468 self.logger.info("Extra InstallOnlyPackage %s %s:%s-%s.%s." % \ 469 (name, installed_inst.get('epoch'), \ 470 installed_inst.get('version'), \ 471 installed_inst.get('release'), \ 472 installed_inst.get('arch'))) 473 if inst.tag == 'Package': 474 Bcfg2.Client.XML.SubElement(extra_entry, \ 475 'Instance', 476 version = installed_inst.get('version'), \ 477 release = installed_inst.get('release')) 478 else: 479 Bcfg2.Client.XML.SubElement(extra_entry, \ 480 'Instance', 481 epoch = str(installed_inst.get('epoch')),\ 482 version = installed_inst.get('version'), \ 483 release = installed_inst.get('release'), \ 484 arch = installed_inst.get('arch', '')) 485 else: 486 # Normal package, only check arch. 487 for installed_inst in pkg_list: 488 not_found = True 489 for inst in instances: 490 if installed_inst.get('arch') == inst.get('arch'): 491 not_found = False 492 break 493 if not_found: 494 self.logger.info("Extra Normal Package Instance %s %s:%s-%s.%s." % \ 495 (name, installed_inst.get('epoch'), \ 496 installed_inst.get('version'), \ 497 installed_inst.get('release'), \ 498 installed_inst.get('arch'))) 499 if inst.tag == 'Package': 500 Bcfg2.Client.XML.SubElement(extra_entry, \ 501 'Instance', 502 version = installed_inst.get('version'), \ 503 release = installed_inst.get('release')) 504 else: 505 Bcfg2.Client.XML.SubElement(extra_entry, \ 506 'Instance', 507 epoch = str(installed_inst.get('epoch')),\ 508 version = installed_inst.get('version'), \ 509 release = installed_inst.get('release'), \ 510 arch = installed_inst.get('arch', '')) 511 else: 512 # Extra package. 513 self.logger.info("No instances of Package %s should be installed." % (name)) 514 for installed_inst in pkg_list: 515 if inst.tag == 'Package': 516 Bcfg2.Client.XML.SubElement(extra_entry, \ 517 'Instance', 744 packages = [entry.get('name') for entry in self.getSupportedEntries()] 745 extras = [] 746 747 for (name, instances) in self.installed.iteritems(): 748 if name not in packages: 749 extra_entry = Bcfg2.Client.XML.Element('Package', name=name, type=self.pkgtype) 750 for installed_inst in instances: 751 self.logger.info("Extra Package %s %s." % \ 752 (name, self.str_evra(installed_inst))) 753 Bcfg2.Client.XML.SubElement(extra_entry, \ 754 'Instance', 755 epoch = str(installed_inst.get('epoch', '')),\ 756 version = installed_inst.get('version'), \ 757 release = installed_inst.get('release'), \ 758 arch = installed_inst.get('arch', '')) 759 extras.append(extra_entry) 760 return extras 761 762 763 def FindExtraInstances(self, pkg_entry, installed_entry): 764 ''' 765 Check for installed instances that are not in the config. 766 Return a Package Entry with Instances to remove, or None if there 767 are no Instances to remove. 768 ''' 769 name = pkg_entry.get('name') 770 extra_entry = Bcfg2.Client.XML.Element('Package', name=name, type=self.pkgtype) 771 instances = [inst for inst in pkg_entry if inst.tag == 'Instance' or inst.tag == 'Package'] 772 if name in self.installOnlyPkgs: 773 for installed_inst in installed_entry: 774 not_found = True 775 for inst in instances: 776 if self.pkg_vr_equal(inst, installed_inst) or \ 777 self.inst_evra_equal(inst, installed_inst): 778 not_found = False 779 break 780 if not_found == True: 781 # Extra package. 782 self.logger.info("Extra InstallOnlyPackage %s %s." % \ 783 (name, self.str_evra(installed_inst))) 784 tmp_entry = Bcfg2.Client.XML.SubElement(extra_entry, 'Instance', \ 518 785 version = installed_inst.get('version'), \ 519 786 release = installed_inst.get('release')) 520 else: 521 Bcfg2.Client.XML.SubElement(extra_entry, \ 787 if installed_inst.get('epoch', None) != None: 788 tmp_entry.set('epoch', str(installed_inst.get('epoch'))) 789 if installed_inst.get('arch', None) != None: 790 tmp_entry.set('arch', installed_inst.get('arch')) 791 else: 792 # Normal package, only check arch. 793 for installed_inst in installed_entry: 794 not_found = True 795 for inst in instances: 796 if installed_inst.get('arch', None) == inst.get('arch', None) or\ 797 inst.tag == 'Package': 798 not_found = False 799 break 800 if not_found: 801 self.logger.info("Extra Normal Package Instance %s %s" % \ 802 (name, self.str_evra(installed_inst))) 803 Bcfg2.Client.XML.SubElement(extra_entry, \ 522 804 'Instance', 523 epoch = str(installed_inst.get('epoch' )),\805 epoch = str(installed_inst.get('epoch', '')),\ 524 806 version = installed_inst.get('version'), \ 525 807 release = installed_inst.get('release'), \ 526 808 arch = installed_inst.get('arch', '')) 527 if len(extra_entry) > 0: 528 extra_packages.append(extra_entry) 529 else: 530 del extra_entry 531 return extra_packages 532 533 534 809 810 if len(extra_entry) == 0: 811 extra_entry = None 812 813 return extra_entry 814 815 def Inventory(self, structures=[]): 816 ''' 817 Wrap the Tool.Inventory() method with its own rpm.TransactionSet() 818 and an explicit closeDB() as the close wasn't happening and DB4 819 locks were getting left behind on the RPM database creating a nice 820 mess. 821 822 ***** Do performance comparison with the transctionset/closeDB 823 moved into rpmtools, which would mean a transactionset/closeDB 824 per VerifyPackage() call (meaning one per RPM package) rather 825 than one for the whole system. 826 ''' 827 self.vp_ts = rpmtools.rpmtransactionset() 828 Bcfg2.Client.Tools.Tool.Inventory(self) 829 # Tool is still an old style class, so super doesn't work. Change it. 830 #super(RPMng, self).Inventory() 831 self.vp_ts.closeDB() 832 833 def str_evra(self, instance): 834 ''' 835 Convert evra dict entries to a string. 836 ''' 837 return '%s:%s-%s.%s' % (instance.get('epoch', '*'), instance.get('version', '*'), 838 instance.get('release', '*'), instance.get('arch', '*')) 839 840 def pkg_vr_equal(self, config_entry, installed_entry): 841 ''' 842 Compare old style entry to installed entry. Which means ignore 843 the epoch and arch. 844 ''' 845 if (config_entry.tag == 'Package' and \ 846 config_entry.get('version') == installed_entry.get('version') and \ 847 config_entry.get('release') == installed_entry.get('release')): 848 return True 849 else: 850 return False 851 852 def inst_evra_equal(self, config_entry, installed_entry): 853 ''' 854 Compare new style instance to installed entry. 855 ''' 856 857 if config_entry.get('epoch', None) != None: 858 epoch = int(config_entry.get('epoch')) 859 else: 860 epoch = None 861 862 if (config_entry.tag == 'Instance' and\ 863 epoch == installed_entry.get('epoch', None) and \ 864 config_entry.get('version') == installed_entry.get('version') and \ 865 config_entry.get('release') == installed_entry.get('release') and \ 866 config_entry.get('arch', None) == installed_entry.get('arch', None)): 867 return True 868 else: 869 return False 870 871 def getinstalledgpg(self): 872 ''' 873 Create a list of installed GPG key IDs. 874 875 The pgp-pubkey package version is the least significant 4 bytes 876 (big-endian) of the key ID which is good enough for our purposes. 877 ''' 878 init_ts = rpmtools.rpmtransactionset() 879 init_ts.setVSFlags(rpm._RPMVSF_NODIGESTS|rpm._RPMVSF_NOSIGNATURES) 880 gpg_hdrs = rpmtools.getheadersbykeyword(init_ts, **{'name':'gpg-pubkey'}) 881 keyids = [ header[rpm.RPMTAG_VERSION] for header in gpg_hdrs] 882 keyids.append('None') 883 init_ts.closeDB() 884 del init_ts 885 return keyids -
trunk/bcfg2/src/lib/Client/Tools/rpmtools.py
r3013 r3029 19 19 20 20 """ 21 __revision__ = ' 0.3'21 __revision__ = '$Revision$' 22 22 23 23 import rpm, optparse, pwd, grp … … 165 165 'version':header[rpm.RPMTAG_VERSION], 166 166 'release':header[rpm.RPMTAG_RELEASE], 167 'arch':header[rpm.RPMTAG_ARCH] } 167 'arch':header[rpm.RPMTAG_ARCH], 168 'gpgkeyid':header.sprintf("%|SIGGPG?{%{SIGGPG:pgpsig}}:{None}|").split()[-1] } 168 169 for header in rts.dbMatch()] 169 170 … … 172 173 Return list of indexs from the rpmdb matching keywords 173 174 ex: getHeadersByKeyword(name='foo', version='1', release='1') 175 176 Can be passed any structure that can be indexed by the pkgspec 177 keyswords as other keys are filtered out. 174 178 175 179 """ … … 181 185 index_mi = index_ts.dbMatch() 182 186 183 # This is wrong! Yes its an issue, but you can't just ignore it.184 # FIX THIS!!!! This is how it is in YUM.185 187 if kwargs.has_key('epoch'): 186 del(kwargs['epoch']) # epochs don't work here for None/0/'0' reasons 187 188 keywords = len(kwargs.keys()) 188 if kwargs['epoch'] != None and kwargs['epoch'] != 'None': 189 kwargs['epoch'] = int(kwargs['epoch']) 190 else: 191 del(kwargs['epoch']) 192 193 keywords = [ key for key in kwargs.keys() \ 194 if key in ('name', 'epoch', 'version', 'release', 'arch')] 195 keywords_len = len(keywords) 189 196 for hdr in index_mi: 190 197 match = 0 191 for keyword in k wargs.keys():198 for keyword in keywords: 192 199 if hdr[keyword] == kwargs[keyword]: 193 200 match += 1 194 if match == keywords :201 if match == keywords_len: 195 202 lst.append(index_mi.instance()) 196 203 del index_mi … … 204 211 Return list of headers from the rpmdb matching keywords 205 212 ex: getHeadersByKeyword(name='foo', version='1', release='1') 213 214 Can be passed any structure that can be indexed by the pkgspec 215 keyswords as other keys are filtered out. 206 216 207 217 """ … … 213 223 header_mi = header_ts.dbMatch() 214 224 215 # This is wrong! Yes its an issue, but you can't just ignore it. 216 # FIX THIS!!!! This is how it is in YUM. 217 # Fixed, I hope. MJTB 20070127. 218 if kwargs.has_key('epoch') and kwargs['epoch'] != None: 219 kwargs['epoch'] = int(kwargs['epoch']) 220 #del(kwargs['epoch']) # epochs don't work here for None/0/'0' reasons 221 222 keywords = len(kwargs.keys()) 225 if kwargs.has_key('epoch'): 226 if kwargs['epoch'] != None and kwargs['epoch'] != 'None': 227 kwargs['epoch'] = int(kwargs['epoch']) 228 else: 229 del(kwargs['epoch']) 230 231 keywords = [ key for key in kwargs.keys() \ 232 if key in ('name', 'epoch', 'version', 'release', 'arch')] 233 keywords_len = len(keywords) 223 234 for hdr in header_mi: 224 235 match = 0 225 for keyword in k wargs.keys():236 for keyword in keywords: 226 237 if hdr[keyword] == kwargs[keyword]: 227 238 match += 1 228 if match == keywords :239 if match == keywords_len: 229 240 lst.append(hdr) 230 241 del header_mi … … 546 557 if 'nodigest' in verify_options: 547 558 vsflags |= rpm._RPMVSF_NODIGESTS 548 if 'nosi fnature' in verify_options:559 if 'nosignature' in verify_options: 549 560 vsflags |= rpm._RPMVSF_NOSIGNATURES 550 561 ovsflags = vp_ts.setVSFlags(vsflags) … … 621 632 file_stat.append(' ') 622 633 623 file_stat.append(fileinfo[0]) 634 file_stat.append(fileinfo[0]) # The filename. 624 635 package_results.setdefault('files', []).append(file_stat) 625 636 … … 723 734 """ 724 735 if reason == rpm.RPMCALLBACK_INST_OPEN_FILE: 725 print 'rpm.RPMCALLBACK_INST_OPEN_FILE' 736 pass 737 #print 'rpm.RPMCALLBACK_INST_OPEN_FILE' 726 738 elif reason == rpm.RPMCALLBACK_INST_CLOSE_FILE: 727 print 'rpm.RPMCALLBACK_INST_CLOSE_FILE' 739 pass 740 #print 'rpm.RPMCALLBACK_INST_CLOSE_FILE' 728 741 elif reason == rpm.RPMCALLBACK_INST_START: 729 print 'rpm.RPMCALLBACK_INST_START' 742 pass 743 #print 'rpm.RPMCALLBACK_INST_START' 730 744 elif reason == rpm.RPMCALLBACK_TRANS_PROGRESS or \ 731 745 reason == rpm.RPMCALLBACK_INST_PROGRESS: 732 print 'rpm.RPMCALLBACK_TRANS_PROGRESS or \ 733 rpm.RPMCALLBACK_INST_PROGRESS' 746 pass 747 #print 'rpm.RPMCALLBACK_TRANS_PROGRESS or \ 748 # rpm.RPMCALLBACK_INST_PROGRESS' 734 749 elif reason == rpm.RPMCALLBACK_TRANS_START: 735 print 'rpm.RPMCALLBACK_TRANS_START' 750 pass 751 #print 'rpm.RPMCALLBACK_TRANS_START' 736 752 elif reason == rpm.RPMCALLBACK_TRANS_STOP: 737 print 'rpm.RPMCALLBACK_TRANS_STOP' 753 pass 754 #print 'rpm.RPMCALLBACK_TRANS_STOP' 738 755 elif reason == rpm.RPMCALLBACK_REPACKAGE_START: 739 print 'rpm.RPMCALLBACK_REPACKAGE_START' 756 pass 757 #print 'rpm.RPMCALLBACK_REPACKAGE_START' 740 758 elif reason == rpm.RPMCALLBACK_REPACKAGE_PROGRESS: 741 print 'rpm.RPMCALLBACK_REPACKAGE_PROGRESS' 759 pass 760 #print 'rpm.RPMCALLBACK_REPACKAGE_PROGRESS' 742 761 elif reason == rpm.RPMCALLBACK_REPACKAGE_STOP: 743 print 'rpm.RPMCALLBACK_REPACKAGE_STOP' 762 pass 763 #print 'rpm.RPMCALLBACK_REPACKAGE_STOP' 744 764 elif reason == rpm.RPMCALLBACK_UNINST_PROGRESS: 745 print 'rpm.RPMCALLBACK_UNINST_PROGRESS' 765 pass 766 #print 'rpm.RPMCALLBACK_UNINST_PROGRESS' 746 767 elif reason == rpm.RPMCALLBACK_UNINST_START: 747 print 'rpm.RPMCALLBACK_UNINST_START' 768 pass 769 #print 'rpm.RPMCALLBACK_UNINST_START' 748 770 elif reason == rpm.RPMCALLBACK_UNINST_STOP: 749 print 'rpm.RPMCALLBACK_UNINST_STOP' 750 print '***Package ', key, ' deleted ***' 771 pass 772 #print 'rpm.RPMCALLBACK_UNINST_STOP' 773 #print '***Package ', key, ' deleted ***' 751 774 # How do we get at this? 752 775 # RPM.modified += key 753 776 elif reason == rpm.RPMCALLBACK_UNPACK_ERROR: 754 print 'rpm.RPMCALLBACK_UNPACK_ERROR' 777 pass 778 #print 'rpm.RPMCALLBACK_UNPACK_ERROR' 755 779 elif reason == rpm.RPMCALLBACK_CPIO_ERROR: 756 print 'rpm.RPMCALLBACK_CPIO_ERROR' 780 pass 781 #print 'rpm.RPMCALLBACK_CPIO_ERROR' 757 782 elif reason == rpm.RPMCALLBACK_UNKNOWN: 758 print 'rpm.RPMCALLBACK_UNKNOWN' 783 pass 784 #print 'rpm.RPMCALLBACK_UNKNOWN' 759 785 else: 760 786 print 'ERROR - Fell through callBack' 761 787 762 print reason, amount, total, key, client_data763 764 def rpm_erase(erase_pkgspec , erase_flags):788 #print reason, amount, total, key, client_data 789 790 def rpm_erase(erase_pkgspecs, erase_flags): 765 791 """ 766 792 pkgspecs is a list of pkgspec dicts specifying packages … … 781 807 erase_ts.setFlags(erase_ts_flags) 782 808 783 idx_list = getindexbykeyword(erase_ts, **erase_pkgspec) 784 if len(idx_list) > 1 and not 'allmatches' in erase_flags: 785 print 'ERROR - Multiple package match for erase' 786 else: 787 for idx in idx_list: 788 erase_ts.addErase(idx) 789 809 for pkgspec in erase_pkgspecs: 810 idx_list = getindexbykeyword(erase_ts, **pkgspec) 811 if len(idx_list) > 1 and not 'allmatches' in erase_flags: 812 #pass 813 print 'ERROR - Multiple package match for erase', pkgspec 814 else: 815 for idx in idx_list: 816 erase_ts.addErase(idx) 817 818 #for te in erase_ts: 819 # print "%s %s:%s-%s.%s" % (te.N(), te.E(), te.V(), te.R(), te.A()) 820 821 erase_problems = [] 790 822 if 'nodeps' not in erase_flags: 791 823 erase_problems = erase_ts.check() 792 824 793 if erase_problems: 794 print 'ERROR - Dependency failures on package erase' 795 print erase_problems 796 else: 825 if erase_problems == []: 797 826 erase_ts.order() 798 827 erase_callback = Rpmtscallback() 799 828 erase_ts.run(erase_callback.callback, 'Erase') 829 #else: 830 # print 'ERROR - Dependency failures on package erase' 831 # print erase_problems 800 832 801 833 erase_ts.closeDB() 834 del erase_ts 802 835 return erase_problems 803 836 … … 1057 1090 elif options.erase: 1058 1091 if options.name: 1059 rpm_erase( cmdline_pkgspec, rpm_options)1092 rpm_erase([cmdline_pkgspec], rpm_options) 1060 1093 else: 1061 1094 print 'You must specify the "--name" option'