def identify(package, product, base, ascii): """List products that include specified package.""" rpm = RPM.from_name(package) if not rpm: error_exit( f"{package} does not appear to be in valid <name>-<version>-<release>.<arch>[.rpm]" ) products = None conn = sqlite3.connect(db) query_values = rpm.to_dict() query_values["base_product"] = base query_values["product"] = product with conn: cur = conn.cursor() if product == "*" and base == "*": cur.execute(sccpdb.search_products_by_rpm, query_values) elif base != "*": cur.execute(sccpdb.create_product_family_temp_table, query_values) cur.execute(sccpdb.search_product_family_by_rpm, query_values) else: cur.execute(sccpdb.search_product_by_rpm, query_values) products = cur.fetchall() cur.close() conn.close() output = pretty_table( products, colnames=["id", "product", "type", "arch", "description"], fmt="ascii" if ascii else "csv", ) print("\n".join(output))
def populateRPMSetFromDirectory(dirname, rpmdb): files = os.listdir(dirname) for fname in files: path = os.path.join(dirname, fname) if os.path.isdir(path): populateRPMSetFromDirectory(path, rpmdb) else: if fname.lower().endswith(".rpm"): rpmdb.addRPM(RPM.fromFile(path))
def endElement(self, name): if name == "package": # add the completed package to the set: self._rpmfile = os.path.join(self.root, self._rpmfile) self.rpmset.addRPM( RPM(self._provides, self._files, self._depends, self._package, self._rpmfile, self._pkgid)) self._cleartemps() if self._elementstack == PrimaryHandler.file_stack: self._files.append(self._currentitem) del self._elementstack[0] self._currentitem = ""
def main(base, rpmlist): """ Identify product(s) associated with a base containing an RPM. \b Legend: ? Doesn't appear to be "<name>-<version>-<release>.<arch>[.rpm]". - Not found in base product. = Found in repo of base product. + From a module or extension that can be enabled on base. """ db = f"{config['DEFAULT']['data_dir']}/{config['SCCP']['db_name']}" if not sccpdb.checkdb(db): error_exit("Please initialise SCCP database with sccpsync.py.") conn = sqlite3.connect(db) with conn: cur = conn.cursor() try: rpm_list = read_rpm_list(rpmlist) except FileNotFoundError: error_exit(f"{rpmlist} does not appear to exit.") cur.execute(sccpdb.create_product_family_temp_table, {"base_product": base}) for line in rpm_list: rpm = RPM.from_name(line) prods = [] if not rpm: key = "?" else: cur.execute(sccpdb.search_product_family_by_rpm, rpm.to_dict()) prods = [p[1] for p in cur.fetchall()] if prods: if base in prods: key = "=" else: key = "+" else: key = "-" print(f"{key} {rpm}") for prod in prodsort(prods, base): print(f" {str(prod)}") print() cur.close() conn.close()
def search(product, name): """List the versions of a package by name.""" conn = sqlite3.connect(db) packages = [] with conn: cur = conn.cursor() if product == "*": cur.execute(sccpdb.search_for_all_versions, {"name": name}) else: cur.execute(sccpdb.search_product_for_all_versions, { "name": name, "product": product }) packages = cur.fetchall() cur.close() conn.close() rpmlist = [] for rpm in packages: rpmlist.append(RPM(rpm[0], rpm[1], rpm[2], rpm[3])) rpmlist.sort(reverse=True) print("\n".join(map(str, rpmlist)))
def test_rpm_invalids(): for s in rpm_list_invalids: assert type(RPM.from_name(s)) == type(None)
def test_rpm_name_strip_noise(): """Parse rpm names with edge white space and .rpm extension""" for s in rpm_list_sorted: assert s == str(RPM.from_name(f" \t {s}.rpm\t\t\t "))
def test_rpm_name_clean(): for s in rpm_list_sorted: assert s == str(RPM.from_name(s))
def getSuseRPMSet(repoPath): _log(1, "Parsing SUSE repository package data...") packages_path = os.path.join(repoPath, "suse/setup/descr/packages") extra_prov_path = os.path.join(repoPath, "suse/setup/descr/EXTRA_PROV") package_fobj = open(packages_path, "r") rpmdb = RPMSet() # check the version of the file; we currently know how to read # version 2: next = package_fobj.readline().strip("\n").strip() if next[:5] == "=Ver:": version = next[len(next) - 3:] if version != "2.0": raise Exception( "Unable to deal with this version of repository: %s" % version) # now read the rest of the file: currentPackage = None inDeps = False inProvs = False for line in package_fobj: line = line.strip("\n") if line[:5] == "=Pkg:": if currentPackage: # we have a package ready to save: rpm = RPM(currentProvides, [], currentDepends, currentPackageName, currentLocation) rpmdb.addRPM(rpm) # we have a new package - re-initialise the variables: currentPackage = None currentPackageName = "" currentArch = "" currentLocation = "" currentProvides = [] currentDepends = [] currentPackage = line[5:].strip().split(" ") currentPackageName = currentPackage[0] currentArch = currentPackage[3] if line[:5] == "=Loc:": values = line[5:].strip().split(" ") # we're not interested in src RPMs: if not (len(values) == 3 and values[2] == "src"): (disc, location) = values[:2] currentLocation = os.path.join( os.path.join(repoPath, "suse/" + currentArch), location) if line[:5] == "-Req:" or line[:5] == "-Prq:": inDeps = False if line[:5] == "-Prv:": inProvs = False if inDeps: currentDepends.append(RPM.depFromString(line)) if inProvs: currentProvides.append(RPM.provideFromString(line)) if line[:5] == "+Req:" or line[:5] == "+Prq:": inDeps = True if line[:5] == "+Prv:": inProvs = True package_fobj.close() # Now read the EXTRA_PROV file if it exists... (ugh) if os.path.exists(extra_prov_path): extraprov_fobj = open(extra_prov_path, "r") for line in extraprov_fobj: line = line.strip("\n") (package, extraprov) = line.split(":\t") extraprov = extraprov.split(" ") rpms = rpmdb.whoProvides(RPM.provideFromString(package)) for rpm in rpms: for prov in extraprov: rpm.addProvides(RPM.provideFromString(prov)) extraprov_fobj.close() # XXX SLES9 has a couple of extra files that aren't listed in its meta-data # We should abstract out classes for dealing with repos but for now we'll # hack this in here: extra_files = ['suse/i586/sles-release-9-82.11.i586.rpm'] for f in extra_files: f = os.path.join(repoPath, f) if os.path.isfile(f): rpmdb.addRPM(RPM.fromFile(f)) return rpmdb
def getSuseRPMSet(repoPath): _log(1, "Parsing SUSE repository package data...") packages_path = os.path.join(repoPath, "suse/setup/descr/packages") extra_prov_path = os.path.join(repoPath, "suse/setup/descr/EXTRA_PROV") package_fobj = open(packages_path, "r") rpmdb = RPMSet() # check the version of the file; we currently know how to read # version 2: next = package_fobj.readline().strip("\n").strip() if next[:5] == "=Ver:": version = next[len(next)-3:] if version != "2.0": raise Exception("Unable to deal with this version of repository: %s" % version) # now read the rest of the file: currentPackage = None inDeps = False inProvs = False for line in package_fobj: line = line.strip("\n") if line[:5] == "=Pkg:": if currentPackage: # we have a package ready to save: rpm = RPM(currentProvides, [], currentDepends, currentPackageName, currentLocation) rpmdb.addRPM(rpm) # we have a new package - re-initialise the variables: currentPackage = None currentPackageName = "" currentArch = "" currentLocation = "" currentProvides = [] currentDepends = [] currentPackage = line[5:].strip().split(" ") currentPackageName = currentPackage[0] currentArch = currentPackage[3] if line[:5] == "=Loc:": values = line[5:].strip().split(" ") # we're not interested in src RPMs: if not (len(values) == 3 and values[2] == "src"): (disc, location) = values[:2] currentLocation = os.path.join(os.path.join(repoPath, "suse/" + currentArch), location) if line[:5] == "-Req:" or line[:5] == "-Prq:": inDeps = False if line[:5] == "-Prv:": inProvs = False if inDeps: currentDepends.append(RPM.depFromString(line)) if inProvs: currentProvides.append(RPM.provideFromString(line)) if line[:5] == "+Req:" or line[:5] == "+Prq:": inDeps = True if line[:5] == "+Prv:": inProvs = True package_fobj.close() # Now read the EXTRA_PROV file if it exists... (ugh) if os.path.exists(extra_prov_path): extraprov_fobj = open(extra_prov_path, "r") for line in extraprov_fobj: line = line.strip("\n") (package, extraprov) = line.split(":\t") extraprov = extraprov.split(" ") rpms = rpmdb.whoProvides(RPM.provideFromString(package)) for rpm in rpms: for prov in extraprov: rpm.addProvides(RPM.provideFromString(prov)) extraprov_fobj.close() # XXX SLES9 has a couple of extra files that aren't listed in its meta-data # We should abstract out classes for dealing with repos but for now we'll # hack this in here: extra_files = ['suse/i586/sles-release-9-82.11.i586.rpm'] for f in extra_files: f = os.path.join(repoPath, f) if os.path.isfile(f): rpmdb.addRPM(RPM.fromFile(f)) return rpmdb