def rpmvercmp(rpm1, rpm2): (e1, v1, r1) = stringToVersion(rpm1) (e2, v2, r2) = stringToVersion(rpm2) if e1 is not None: e1 = str(e1) if e2 is not None: e2 = str(e2) rc = rpm.labelCompare((e1, v1, r1), (e2, v2, r2)) return rc
def version_compare(evr1, evr2): """Compare the EVRs (epoch, version, release) of two RPMs and return - -1 if the first EVR is older than the second, - 0 if the two arguments are equal, - 1 if the first EVR is newer than the second. Each EVR may be specified as a string (of the form "V-R" or "E:V-R"), or as a 3-element tuple or list. """ if is_string(evr1): epoch1, version1, release1 = stringToVersion(evr1) elif isinstance(evr1, bytes): epoch1, version1, release1 = stringToVersion(evr1.decode()) else: epoch1, version1, release1 = evr1 if is_string(evr2): epoch2, version2, release2 = stringToVersion(evr2) elif isinstance(evr2, bytes): epoch2, version2, release2 = stringToVersion(evr2.decode()) else: epoch2, version2, release2 = evr2 return rpm.labelCompare((epoch1, version1, release1), (epoch2, version2, release2))
def parse_smart_pkglist(output): pkglist = {} for line in output.splitlines(): if line == '': continue fields = line.split() pkgname = fields[0] (version, arch) = fields[1].split('@') if pkgname not in pkglist: pkglist[pkgname] = {} pkglist[pkgname][arch] = version elif arch not in pkglist[pkgname]: pkglist[pkgname][arch] = version else: stored_ver = pkglist[pkgname][arch] # The rpm.labelCompare takes version broken into 3 components # It returns: # 1, if first arg is higher version # 0, if versions are same # -1, if first arg is lower version rc = rpm.labelCompare(stringToVersion(version), stringToVersion(stored_ver)) if rc > 0: # Update version pkglist[pkgname][arch] = version return pkglist
def store_package_deps(db, package_obj): pkg_id = package_obj.id ts = rpm.ts() rpm_file = package_obj.get_lob_fd("package") header = ts.hdrFromFdno(rpm_file.fileno()) files = header.fiFromHeader() logging.debug("{0} contains {1} files".format(package_obj.nvra(), len(files))) for f in files: new = PackageDependency() new.package_id = pkg_id new.type = "PROVIDES" new.name = f[0] new.flags = 0 db.session.add(new) provides = header.dsFromHeader('providename') for p in provides: new = PackageDependency() new.package_id = pkg_id new.type = "PROVIDES" new.name = p.N() new.flags = p.Flags() evr = p.EVR() if len(evr): new.epoch, new.version, new.release = rpmutils.stringToVersion(evr) db.session.add(new) requires = header.dsFromHeader('requirename') for r in requires: new = PackageDependency() new.package_id = pkg_id new.type = "REQUIRES" new.name = r.N() new.flags = r.Flags() evr = r.EVR() if len(evr): new.epoch, new.version, new.release = rpmutils.stringToVersion(evr) db.session.add(new) conflicts = header.dsFromHeader('conflictname') for c in conflicts: new = PackageDependency() new.package_id = pkg_id new.type = "CONFLICTS" new.name = c.N() new.flags = c.Flags() evr = c.EVR() if len(evr): new.epoch, new.version, new.release = rpmutils.stringToVersion(evr) db.session.add(new) rpm_file.close() db.session.flush()
def check_version_inc(self, version, prj, pkg): error, specob = self._get_spec_file(prj, pkg, None) if error: print error #don't care if we can't get target package spec return None src_hdrs = [pkg for pkg in specob.packages if pkg.header.isSource()][0] spec_version = "%s-%s" % (src_hdrs.header[rpm.RPMTAG_VERSION], src_hdrs.header[rpm.RPMTAG_RELEASE]) version_comparison = compareEVR(stringToVersion(version), stringToVersion(spec_version)) if version_comparison == 1: return None else: return "Incoming version %s is not higher than current version %s" % (version, spec_version)
def check_version_inc(self, version, prj, pkg): error, specob = self._get_spec_file(prj, pkg, None) if error: print error #don't care if we can't get target package spec return None src_hdrs = [pkg for pkg in specob.packages if pkg.header.isSource()][0] spec_version = "%s-%s" % (src_hdrs.header[rpm.RPMTAG_VERSION], src_hdrs.header[rpm.RPMTAG_RELEASE]) version_comparison = compareEVR(stringToVersion(version), stringToVersion(spec_version)) if version_comparison == 1: return None else: return "Incoming version %s is not higher than current version %s" % (version, spec_version)
def main(): enable_features = [] if len(sys.argv) < 1: print "Usage: %s" % sys.argv[0] sys.exit(1) elif len(sys.argv) > 1: enable_features = sys.argv[1:] for feature in enable_features: if not is_supported_feature(feature): print "Error: %s is not supported feature \n" % feature print "Please refer README.md" sys.exit(1) enable_features += constants.COMMON_PATCH version = subprocess.check_output( ['rpm', '-qa', 'openstack-tripleo-heat-templates']) if not version: print "ERROR: Make sure openstack-tripleo-heat-templates" \ " package is installed before running this script" sys.exit(1) (e0, v0, r0) = stringToVersion(version) (e1, v1, r1) = stringToVersion(constants.VERSION_1_CHECK) (e2, v2, r2) = stringToVersion(constants.VERSION_2_CHECK) (e3, v3, r3) = stringToVersion(constants.VERSION_3_CHECK) # Compare versions version_1_rc = version_compare((e0, v0, r0), (e1, v1, r1)) version_2_rc = version_compare((e0, v0, r0), (e2, v2, r2)) version_3_rc = version_compare((e0, v0, r0), (e3, v3, r3)) if version_1_rc <= 0: diff_version = constants.VERSION_1_DIFF elif version_1_rc > 0 and version_2_rc <= 0: diff_version = constants.VERSION_2_DIFF elif version_2_rc > 0 and version_3_rc <= 0: diff_version = constants.VERSION_3_DIFF elif version_3_rc > 0: print "Not supported for %s" % version sys.exit(1) # Apply appropriate diff apply_patch(diff_version, enable_features)
def string_to_prco_tuple(prcoString): """returns a prco tuple (name, flags, (e, v, r)) for a string""" if type(prcoString) == tuple: (n, f, v) = prcoString else: n = prcoString f = v = None # We love GPG keys as packages, esp. awesome provides like: # gpg(Fedora (13) <*****@*****.**>) if n[0] != '/' and not n.startswith("gpg("): # not a file dep - look at it for being versioned prco_split = n.split() if len(prco_split) == 3: n, f, v = prco_split # now we have 'n, f, v' where f and v could be None and None if f is not None and f not in constants.LETTERFLAGS: if f not in constants.SYMBOLFLAGS: try: f = flagToString(int(f)) except (ValueError, TypeError) as e: raise Errors.MiscError('Invalid version flag: %s' % f) else: f = constants.SYMBOLFLAGS[f] if type(v) in (bytes, type(None), str): (prco_e, prco_v, prco_r) = stringToVersion(v) elif type(v) in (tuple, list): (prco_e, prco_v, prco_r) = v #now we have (n, f, (e, v, r)) for the thing specified return (n, f, (prco_e, prco_v, prco_r))
def __cmp__(self, evr): if isinstance(evr, str): evr = stringToVersion(evr) else: raise TypeError('PackageVersion compares to "[E:]V[-R]" string') if evr[2] is None: pkg_evr = (self.evr[0], self.evr[1], None) else: pkg_evr = self.evr return rpm.labelCompare(pkg_evr, evr)
def version_compare(evr1, evr2): """Compare the EVRs (epoch, version, release) of two RPMs and return - -1 if the first EVR is older than the second, - 0 if the two arguments are equal, - 1 if the first EVR is newer than the second. Each EVR may be specified as a string (of the form "V-R" or "E:V-R"), or as a 3-element tuple or list. """ if isinstance(evr1, basestring): epoch1, version1, release1 = stringToVersion(evr1) else: epoch1, version1, release1 = evr1 if isinstance(evr2, basestring): epoch2, version2, release2 = stringToVersion(evr2) else: epoch2, version2, release2 = evr2 return rpm.labelCompare((epoch1, version1, release1), (epoch2, version2, release2))
def versioncompare(versions): arch_list = getArchList() candidate_arch1 = versions[0].split(".")[-1] candidate_arch2 = versions[1].split(".")[-1] # The first version number passed to this method is always a valid nevra (the current version) # If the second version number looks like it does not contain a valid arch # then we'll chop the arch component (assuming it *is* a valid one) from the first version string # so we're only comparing the evr portions. if (candidate_arch2 not in arch_list) and (candidate_arch1 in arch_list): final_version1 = versions[0].replace("." + candidate_arch1,"") else: final_version1 = versions[0] final_version2 = versions[1] (e1, v1, r1) = stringToVersion(final_version1) (e2, v2, r2) = stringToVersion(final_version2) evr_comparison = compareEVR((e1, v1, r1), (e2, v2, r2)) outpipe.write("%(e)s\n" % { 'e': evr_comparison }) outpipe.flush()
def versioncompare(versions): arch_list = getArchList() candidate_arch1 = versions[0].split(".")[-1] candidate_arch2 = versions[1].split(".")[-1] # The first version number passed to this method is always a valid nevra (the current version) # If the second version number looks like it does not contain a valid arch # then we'll chop the arch component (assuming it *is* a valid one) from the first version string # so we're only comparing the evr portions. if (candidate_arch2 not in arch_list) and (candidate_arch1 in arch_list): final_version1 = versions[0].replace("." + candidate_arch1, "") else: final_version1 = versions[0] final_version2 = versions[1] (e1, v1, r1) = stringToVersion(final_version1) (e2, v2, r2) = stringToVersion(final_version2) evr_comparison = compareEVR((e1, v1, r1), (e2, v2, r2)) outpipe.write("%(e)s\n" % {'e': evr_comparison}) outpipe.flush()
def _genDeptup(name, flags, version): """ Given random stuff, generate a usable dep tuple. """ if flags == 0: flags = None if type(version) is types.StringType: (r_e, r_v, r_r) = miscutils.stringToVersion(version) # would this ever be a ListType? elif type(version) in (types.TupleType, types.ListType): (r_e, r_v, r_r) = version else: # FIXME: This isn't always type(version) is types.NoneType: # ...not sure what it is though, come back to this r_e = r_v = r_r = None deptup = (name, misc.share_data(flags), (misc.share_data(r_e), misc.share_data(r_v), misc.share_data(r_r))) return misc.share_data(deptup)
# From http://stackoverflow.com/questions/3206319/how-do-i-compare-rpm-versions-in-python # # (c) 2014 Steve Kehlet import rpm import sys from rpmUtils.miscutils import stringToVersion if len(sys.argv) != 3: print "Usage: %s <rpm1> <rpm2>" sys.exit(1) def vercmp((e1, v1, r1), (e2, v2, r2)): return rpm.labelCompare((e1, v1, r1), (e2, v2, r2)) (e1, v1, r1) = stringToVersion(sys.argv[1]) (e2, v2, r2) = stringToVersion(sys.argv[2]) rc = vercmp((e1, v1, r1), (e2, v2, r2)) if rc > 0: #print "%s:%s-%s is newer" % (e1, v1, r1) sys.exit(-1) elif rc == 0: sys.exit(0) elif rc < 0: #print "%s:%s-%s is newer" % (e2, v2, r2) sys.exit(1)
prco_split = n.split() if len(prco_split) == 3: n, f, v = prco_split # now we have 'n, f, v' where f and v could be None and None if f is not None and f not in constants.LETTERFLAGS: if f not in constants.SYMBOLFLAGS: try: f = flagToString(int(f)) except (ValueError,TypeError), e: raise Errors.MiscError, 'Invalid version flag: %s' % f else: f = constants.SYMBOLFLAGS[f] if type(v) in (types.StringType, types.NoneType, types.UnicodeType): (prco_e, prco_v, prco_r) = stringToVersion(v) elif type(v) in (types.TupleType, types.ListType): (prco_e, prco_v, prco_r) = v #now we have (n, f, (e, v, r)) for the thing specified return (n, f, (prco_e, prco_v, prco_r)) def refineSearchPattern(arg): """Takes a search string from the cli for Search or Provides and cleans it up so it doesn't make us vomit""" if re.search('[*{}?+]|\[.+\]', arg): restring = fnmatch.translate(arg) else: restring = re.escape(arg)
def string_to_prco_tuple(prcoString): prco_split = prcoString.split() n, f, v = prco_split (prco_e, prco_v, prco_r) = stringToVersion(v) return (n, f, (prco_e, prco_v, prco_r))
prco_split = n.split() if len(prco_split) == 3: n, f, v = prco_split # now we have 'n, f, v' where f and v could be None and None if f is not None and f not in constants.LETTERFLAGS: if f not in constants.SYMBOLFLAGS: try: f = flagToString(int(f)) except (ValueError, TypeError), e: raise Errors.MiscError, 'Invalid version flag: %s' % f else: f = constants.SYMBOLFLAGS[f] if type(v) in (types.StringType, types.NoneType, types.UnicodeType): (prco_e, prco_v, prco_r) = stringToVersion(v) elif type(v) in (types.TupleType, types.ListType): (prco_e, prco_v, prco_r) = v #now we have (n, f, (e, v, r)) for the thing specified return (n, f, (prco_e, prco_v, prco_r)) def refineSearchPattern(arg): """Takes a search string from the cli for Search or Provides and cleans it up so it doesn't make us vomit""" if re.search('[*{}?+]|\[.+\]', arg): restring = fnmatch.translate(arg) else: restring = re.escape(arg)
def query(self): """ Check current patch state """ if not check_install_uuid(): LOG.info("Failed install_uuid check. Skipping query") return False if not self.audit_smart_config(): # Set a state to "unknown"? return False try: subprocess.check_output(smart_update, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as e: LOG.error("Failed to update smartpm") LOG.error("Command output: %s" % e.output) # Set a state to "unknown"? return False # Generate a unique query id self.query_id = random.random() self.changes = False self.installed = {} self.to_install = {} self.to_remove = [] self.missing_pkgs = [] # Get the repo data pkgs_installed = {} pkgs_base = {} pkgs_updates = {} try: output = subprocess.check_output(smart_query_installed) pkgs_installed = self.parse_smart_pkglist(output) except subprocess.CalledProcessError as e: LOG.error("Failed to query installed pkgs: %s" % e.output) # Set a state to "unknown"? return False try: output = subprocess.check_output(smart_query_base) pkgs_base = self.parse_smart_pkglist(output) except subprocess.CalledProcessError as e: LOG.error("Failed to query base pkgs: %s" % e.output) # Set a state to "unknown"? return False try: output = subprocess.check_output(smart_query_updates) pkgs_updates = self.parse_smart_pkglist(output) except subprocess.CalledProcessError as e: LOG.error("Failed to query patched pkgs: %s" % e.output) # Set a state to "unknown"? return False # There are four possible actions: # 1. If installed pkg is not in base or updates, remove it. # 2. If installed pkg version is higher than highest in base # or updates, downgrade it. # 3. If installed pkg version is lower than highest in updates, # upgrade it. # 4. If pkg in grouplist is not in installed, install it. for pkg in pkgs_installed: for arch in pkgs_installed[pkg]: installed_version = pkgs_installed[pkg][arch] updates_version = self.get_pkg_version(pkgs_updates, pkg, arch) base_version = self.get_pkg_version(pkgs_base, pkg, arch) if updates_version is None and base_version is None: # Remove it self.to_remove.append(pkg) self.changes = True continue compare_version = updates_version if compare_version is None: compare_version = base_version # Compare the installed version to what's in the repo rc = rpm.labelCompare(stringToVersion(installed_version), stringToVersion(compare_version)) if rc == 0: # Versions match, nothing to do. continue else: # Install the version from the repo self.to_install[pkg] = "@".join([compare_version, arch]) self.installed[pkg] = "@".join([installed_version, arch]) self.changes = True # Look for new packages self.check_groups() LOG.info("Patch state query returns %s" % self.changes) LOG.info("Installed: %s" % self.installed) LOG.info("To install: %s" % self.to_install) LOG.info("To remove: %s" % self.to_remove) LOG.info("Missing: %s" % self.missing_pkgs) return True
def store_rpm_deps(db, package, nogpgcheck=False): """ Save RPM dependencies of `package` to storage. Expects pyfaf.storage.opsys.Package object. """ pkg_id = package.id ts = rpm.ts() rpm_file = package.get_lob_fd("package") if not rpm_file: log.warning("Package {0} has no lob stored".format(package.name)) return False if nogpgcheck: ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES) try: header = ts.hdrFromFdno(rpm_file.fileno()) except rpm.error as exc: log.error("rpm error: {0}".format(exc)) return False files = header.fiFromHeader() log.debug("{0} contains {1} files".format(package.nvra(), len(files))) # Invalid name for type variable # pylint: disable-msg=C0103 for f in files: new = PackageDependency() new.package_id = pkg_id new.type = "PROVIDES" new.name = f[0] new.flags = 0 db.session.add(new) provides = header.dsFromHeader('providename') for p in provides: new = PackageDependency() new.package_id = pkg_id new.type = "PROVIDES" new.name = p.N() new.flags = p.Flags() evr = p.EVR() if evr: new.epoch, new.version, new.release = rpmutils.stringToVersion(evr) db.session.add(new) requires = header.dsFromHeader('requirename') for r in requires: new = PackageDependency() new.package_id = pkg_id new.type = "REQUIRES" new.name = r.N() new.flags = r.Flags() evr = r.EVR() if evr: new.epoch, new.version, new.release = rpmutils.stringToVersion(evr) db.session.add(new) conflicts = header.dsFromHeader('conflictname') for c in conflicts: new = PackageDependency() new.package_id = pkg_id new.type = "CONFLICTS" new.name = c.N() new.flags = c.Flags() evr = c.EVR() if evr: new.epoch, new.version, new.release = rpmutils.stringToVersion(evr) db.session.add(new) # pylint: enable-msg=C0103 rpm_file.close() db.session.flush() return True
def string_to_prco_tuple(prcoString): prco_split = prcoString.split() n, f, v = prco_split (prco_e, prco_v, prco_r) = stringToVersion(v) return (n, f, (prco_e, prco_v, prco_r))
def compare_versions(self, ver1, ver2): '''Compare two package versions. Return -1 for ver < ver2, 0 for ver1 == ver2, and 1 for ver1 > ver2.''' # Used by crashdb.py (i.e. the frontends) return compareEVR(stringToVersion(ver1),stringToVersion(ver2))
# # (c) 2014 Steve Kehlet import rpm import sys from rpmUtils.miscutils import stringToVersion if len(sys.argv) != 3: print "Usage: %s <rpm1> <rpm2>" sys.exit(1) def vercmp((e1, v1, r1), (e2, v2, r2)): return rpm.labelCompare((e1, v1, r1), (e2, v2, r2)) (e1, v1, r1) = stringToVersion(sys.argv[1]) (e2, v2, r2) = stringToVersion(sys.argv[2]) rc = vercmp((e1, v1, r1), (e2, v2, r2)) if rc > 0: #print "%s:%s-%s is newer" % (e1, v1, r1) sys.exit(-1) elif rc == 0: sys.exit(0) elif rc < 0: #print "%s:%s-%s is newer" % (e2, v2, r2) sys.exit(1)
def store_rpm_deps(db, package, nogpgcheck=False): """ Save RPM dependencies of `package` to storage. Expects pyfaf.storage.opsys.Package object. """ pkg_id = package.id ts = rpm.ts() rpm_file = package.get_lob_fd("package") if not rpm_file: log.warning("Package {0} has no lob stored".format(package.name)) return False if nogpgcheck: ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES) try: header = ts.hdrFromFdno(rpm_file.fileno()) except rpm.error as exc: log.error("rpm error: {0}".format(exc)) return False files = header.fiFromHeader() log.debug("{0} contains {1} files".format(package.nvra(), len(files))) # Invalid name for type variable # pylint: disable-msg=C0103 for f in files: new = PackageDependency() new.package_id = pkg_id new.type = "PROVIDES" new.name = f[0] new.flags = 0 db.session.add(new) provides = header.dsFromHeader('providename') for p in provides: new = PackageDependency() new.package_id = pkg_id new.type = "PROVIDES" new.name = p.N() new.flags = p.Flags() evr = p.EVR() if len(evr): new.epoch, new.version, new.release = rpmutils.stringToVersion(evr) db.session.add(new) requires = header.dsFromHeader('requirename') for r in requires: new = PackageDependency() new.package_id = pkg_id new.type = "REQUIRES" new.name = r.N() new.flags = r.Flags() evr = r.EVR() if len(evr): new.epoch, new.version, new.release = rpmutils.stringToVersion(evr) db.session.add(new) conflicts = header.dsFromHeader('conflictname') for c in conflicts: new = PackageDependency() new.package_id = pkg_id new.type = "CONFLICTS" new.name = c.N() new.flags = c.Flags() evr = c.EVR() if len(evr): new.epoch, new.version, new.release = rpmutils.stringToVersion(evr) db.session.add(new) # pylint: enable-msg=C0103 rpm_file.close() db.session.flush() return True