def install(self, transaction): 'Install rpm packages given a dictionary of packages.' # Check that all packages are available. if (len(transaction) < 1) or not transaction: raise ex.install_error, "unrecogniced transaction format." missingfiles = [] for package in transaction.values(): if not package.has_key('localfilename'): msg = "%s has no 'localfilename'" %package['name'] missingfiles.append(msg) continue if not os.path.isfile(package['localfilename']): missingfiles.append(package['localfilename']) if len(missingfiles) > 0: raise ex.install_error("Missing files",missingfiles) if self.oldrpm: ts = rpm.TransactionSet(self.root, self.db) else: ts = rpm.TransactionSet(self.root) ts.setVSFlags(~(rpm.RPMVSF_NODSA|rpm.RPMVSF_NORSA)) self.filenames = {} self.modes = {} ts_names = [] for package in transaction.values(): if package['flag'] == "upgrade": transactionmode = "u" elif package['flag'] == "install": transactionmode = "i" else: errmsg = "Mode '%s' for package '%s' not recognized." \ % (package['flag'], package['name']) raise ex.install_error(errmsg) fd = os.open(package['localfilename'], os.O_RDONLY) try: if self.oldrpm: hdr = rpm.headerFromPackage(fd)[0] else: headerts = rpm.TransactionSet(self.root) headerts.setVSFlags(~(rpm.RPMVSF_NODSA|rpm.RPMVSF_NORSA)) hdr = headerts.hdrFromFdno(fd) except rpm.error, e: if str(e) == 'public key not available': self.log.write_stdout('\nThe public key associated with this package was not found.\n\n') self.filenames[hdr[rpm.RPMTAG_NAME]] = package['localfilename'] self.modes[hdr[rpm.RPMTAG_NAME]] = package['flag'] os.close(fd) if self.oldrpm: ts.add(hdr, hdr, transactionmode) else: #RPM>=4.1 needs this ts.addInstall(hdr, hdr, transactionmode) ts_names.append(package['name'])
def erase(self, packagenames): 'Erase packages.' if self.oldrpm: names = "" for package in packagenames: names = package + " " + names command = "rpm -e %s\n" %names fd = os.popen(command) output = fd.read() exitval = fd.close() if exitval: message = "Error while removing packages:\n" +\ "Exitcode: %s\nOutput: %s\n\n" %(exitval, output) sys.stderr.write(message) return None else: ts = rpm.TransactionSet(self.root) ts.setVSFlags(~(rpm.RPMVSF_NODSA|rpm.RPMVSF_NORSA)) ts_names = "" for package in packagenames: ts_names += package + ' ' try: ts.addErase(package) except rpm.error: raise ex.not_installed_error, package deps = ts.check() if deps: deps_message = "" for ((name, version, release), (reqname, reqversion), flags, suggest, sense) in deps: if sense == rpm.RPMDEP_SENSE_REQUIRES: if reqversion == "" or reqversion == None: deps_message += \ "\t'%s' requires '%s'.\n" % \ (name, reqname) else: deps_message += \ "\t'%s' requires '%s' version '%s'.\n"% \ (name, reqname, reqversion) raise ex.erase_error, \ ":\n\t%s\n%s\n" % (ts_names, deps_message) \ # Erase the rpms errors = ts.run(self._erase_callback, '') if errors: error_description = "RPM: " for error in errors: error_description = error_description + str(error[0]) + "\n" raise ex.install_error(error_description, ts_names)
deps = ts.check() ts.order() if deps: deps_message = "" for ((name, version, release), (reqname, reqversion), flags, suggest, sense) in deps: if sense == rpm.RPMDEP_SENSE_REQUIRES: if reqversion == "" or reqversion == None: deps_message += \ "\tPackage '%s' requires '%s'.\n" % \ (name, reqname) else: deps_message += \ "\tPackage '%s' requires '%s' version '%s'.\n"% \ (name, reqname, reqversion) raise ex.install_error(deps_message,ts_names) # # FIXME: Check for local conflicts and give nice output like the # above dep check. This is interesting because of possible file # conflicts filling the console, thus making it hard to see the # real problem.... # # Install the rpms if self.oldrpm: errors = ts.run(0, 0, self._install_callback, '') else: #RPM>=4.1 needs this errors = ts.run(self._install_callback, '')