def container_to_etree(obj, parent=None, pprefix=_PARAM_PREFIX): """ Convert a dict-like object to XML ElementTree. :param obj: Container instance to convert to :param parent: XML ElementTree parent node object or None :param pprefix: Special parameter name prefix """ if not anyconfig.mdicts.is_dict_like(obj): return # All attributes and text should be set already. (attrs, text, children) = _gen_tags(pprefix) for key, val in anyconfig.compat.iteritems(obj): if key == attrs: for attr, aval in anyconfig.compat.iteritems(val): parent.set(attr, aval) elif key == text: parent.text = val elif key == children: for child in val: # child should be a dict-like object. for ckey, cval in anyconfig.compat.iteritems(child): celem = ET.Element(ckey) container_to_etree(cval, celem, pprefix) parent.append(celem) else: elem = ET.Element(key) container_to_etree(val, elem, pprefix) return ET.ElementTree(elem)
def load_from_string(self, content, to_container, **kwargs): """ Load config from XML snippet (a string `content`). :param content: XML snippet (a string) :param to_container: callble to make a container object :param kwargs: optional keyword parameters passed to :return: Dict-like object holding config parameters """ root = ET.ElementTree(ET.fromstring(content)).getroot() return etree_to_container(root, to_container)
def pkgdata_from_primary_xml_itr(filepath): """ :param filepath: Path to primary.xml[.gz] """ content = gzip.GzipFile(filename=filepath).read() root = ET.ElementTree(ET.fromstring(content)).getroot() for pkg in root.findall(_ns("package")): try: yield dict(name=pkg.find(_ns("name")).text, evr=pkg.find(_ns("version")).attrib, arch=pkg.find(_ns("arch")).text, size=pkg.find(_ns("size")).attrib) except: LOG.warn("Skipped: ", pkg.find(_ns("name")).text) pass
def updateinfo_xml_itr(updateinfo): """ :param updateinfo: the content of updateinfo.xml :: str """ root = ET.ElementTree(ET.fromstring(updateinfo)).getroot() for upd in root.findall("update"): uinfo = upd.attrib for k in "id title severity rights summary description".split(): elem = upd.find(k) if elem is not None: uinfo[k] = elem.text for k in "issued updated".split(): uinfo[k] = upd.find(k).attrib["date"] uinfo["refs"] = [r.attrib for r in upd.findall(".//reference")] uinfo["packages"] = [ dict(filename=p.find("filename").text, **p.attrib) for p in upd.findall(".//package") ] yield uinfo
def other_xml_itr(content): """ :param content: the content of other.xml :: str """ ns = "http://linux.duke.edu/metadata/other" root = ET.ElementTree(ET.fromstring(content)).getroot() for pkg in root.getchildren(): pinfo = pkg.attrib LOG.debug("Found package: %s", str(pinfo)) vinfo = pkg.find("{%s}version" % ns).attrib pinfo["version"] = vinfo["ver"] pinfo["release"] = vinfo["rel"] pinfo["epoch"] = vinfo["epoch"] pinfo["evr"] = operator.itemgetter("epoch", "version", "release")(pinfo) pinfo["changelogs"] = \ list(_changelog_itr(pkg.findall("{%s}changelog" % ns))) yield pinfo
def get_errata_list_from_updateinfo_by_repofile(rid, basearch="x86_64"): """ Try to fetch the content of given repo metadata xml from remote. :param rid: ID of the repo from RH CDN, ex. rhel-7-server-rpms """ timeout = 60 * 5 try: repos = anyconfig.load("/etc/yum.repos.d/*.repo", ac_parser="ini") repo = repos.get(rid, None) if repo is None: LOG.error("Failed to get repo info: %r", rid) return None rparams = dict(timeout=timeout) if "sslclientcert" in repo and "sslclientkey" in repo: rparams["cert"] = (repo["sslclientcert"], repo["sslclientkey"]) if "sslcacert" in repo: rparams["verify"] = repo["sslcacert"] try: m = re.match(r"Red Hat Enterprise Linux (\d+) .*", repo["name"]) relver = "%dServer" % int(m.groups()[0]) if m else "7Server" except (AttributeError, IndexError): relver = None baseurl = expand_baseurl_in_repofile(repo["baseurl"], relver) repomd_xml_url = os.path.join(baseurl, "repodata/repomd.xml") LOG.info("Try to fetch repomd.xml: %s", repomd_xml_url) resp = requests.get(repomd_xml_url, **rparams) if not resp.ok: LOG.error("Failed to get repomd.xml from %s", baseurl) return None LOG.debug("Try to parse repomd.xml...") root = ET.ElementTree(ET.fromstring(resp.text)).getroot() ns = "http://linux.duke.edu/metadata/repo" es = root.findall(".//{%s}location" % ns) us = [ e.attrib["href"] for e in es if "updateinfo.xml" in e.attrib["href"] ] if not us: LOG.error("Failed to find the url %s", repomd_xml_url) return None upd_url = os.path.join(baseurl, us[0]) LOG.debug("Try to fetch updateinfo.xml: %s", upd_url) resp = requests.get(upd_url, **rparams) if not resp.ok: LOG.error("Failed to get updateinfo.xml from %s", upd_url) return None updgz = resp.content uinfo = gzip.GzipFile(fileobj=StringIO.StringIO(updgz)).read() return sorted(updateinfo_xml_itr(uinfo), key=operator.itemgetter("issued")) except Exception as exc: raise RuntimeError("Failed: exc=%r" % exc)
def etree_getroot_fromstring(s): """ :param s: A XML string :return: etree object gotten by parsing ``s`` """ return etree.ElementTree(etree.fromstring(s)).getroot()