[Kimchi-devel] [PATCH V9 4/7] manually manage the metadata element

Royce Lv lvroyce at linux.vnet.ibm.com
Mon Apr 28 07:06:24 UTC 2014


Reviewed-by: Royce Lv<lvroyce at linux.vnet.ibm.com>
On 2014年04月25日 22:14, shaohef at linux.vnet.ibm.com wrote:
> From: ShaoHe Feng <shaohef at linux.vnet.ibm.com>
>
> virDomain.metadata and virDomain.setMetadata does not work in all livirt
> versions used in the supported distros.
>
> So if libvirt do not support these two API.
>
> let kimchi manually manage the metadata element
>
> Signed-off-by: ShaoHe Feng <shaohef at linux.vnet.ibm.com>
> Signed-off-by: Royce Lv <lvroyce at linux.vnet.ibm.com>
> ---
>   src/kimchi/model/utils.py | 93 ++++++++++++++++++++++++++++++++++++++++-------
>   1 file changed, 79 insertions(+), 14 deletions(-)
>
> diff --git a/src/kimchi/model/utils.py b/src/kimchi/model/utils.py
> index 9b94a06..257b9e7 100644
> --- a/src/kimchi/model/utils.py
> +++ b/src/kimchi/model/utils.py
> @@ -18,8 +18,10 @@
>   # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
>
>   from kimchi.exception import OperationFailed
> +from kimchi.model.config import CapabilitiesModel
>   import libvirt
> -from lxml import etree
> +from lxml import etree, objectify
> +from lxml.builder import E, ElementMaker
>
>
>   KIMCHI_META_URL = "https://github.com/kimchi-project/kimchi/metadata/"
> @@ -36,6 +38,16 @@ def get_vm_name(vm_name, t_name, name_list):
>       raise OperationFailed("KCHUTILS0003E")
>
>
> +def create_metadata_node(element):
> +     # create the xml using "element"
> +    if CapabilitiesModel().metadata_support:
> +        return E
> +    else:
> +        return ElementMaker(namespace=KIMCHI_META_URL + element,
> +                            nsmap={KIMCHI_NAMESPACE:
> +                                   KIMCHI_META_URL + element})
> +
> +
>   def get_vm_config_flag(dom, mode="persistent"):
>       # libvirt.VIR_DOMAIN_AFFECT_CURRENT is 0
>       # VIR_DOMAIN_AFFECT_LIVE is 1, VIR_DOMAIN_AFFECT_CONFIG is 2
> @@ -49,20 +61,73 @@ def get_vm_config_flag(dom, mode="persistent"):
>       return flag[mode]
>
>
> -def set_metadata_node(dom, meta_xml, mode="all"):
> +def _kimchi_set_metadata_node(dom, meta_xml):
>       element = etree.fromstring(meta_xml)
> -    # From libvirt doc, Passing None for @metadata says to remove that element
> -    # from the domain XML (passing the empty string leaves the element present)
> -    # Do not support remove the old metadata
> -    dom.setMetadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT, meta_xml,
> -                    KIMCHI_NAMESPACE, KIMCHI_META_URL + element.tag,
> -                    flags=get_vm_config_flag(dom, mode))
> +    # some other tools will not let libvirt create a persistent
> +    # configuration, raise exception.
> +    if not dom.isPersistent():
> +        msg = 'The VM has not a persistent configuration'
> +        raise OperationFailed("KCHVM0030E",
> +                              {'name': dom.name(), "err": msg})
> +    xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE)
> +    root = etree.fromstring(xml)
> +    metadata = root.find("metadata")
> +    if metadata is None:
> +        metadata = E.metadata()
> +        root.append(metadata)
> +    old_elem = metadata.find(element.tag)
> +    (metadata.replace(old_elem, element) if old_elem is not None
> +     else metadata.append(element))
>
> +    dom.connect().defineXML(etree.tostring(root))
>
> -def get_metadata_node(dom, element, mode="current"):
> -    try:
> -        return dom.metadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT,
> -                            KIMCHI_META_URL + element,
> -                            flags=get_vm_config_flag(dom, mode))
> -    except libvirt.libvirtError:
> +
> +def set_metadata_node(dom, meta_xml, mode="all"):
> +    if CapabilitiesModel().metadata_support:
> +        element = etree.fromstring(meta_xml)
> +        # From libvirt doc, Passing None for @metadata says to remove that
> +        # element from the domain XML (passing the empty string leaves the
> +        # element present).  Do not support remove the old metadata.
> +        dom.setMetadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT, meta_xml,
> +                        KIMCHI_NAMESPACE, KIMCHI_META_URL + element.tag,
> +                        flags=get_vm_config_flag(dom, mode))
> +    else:
> +    # FIXME remove this code when all distro libvirt supports metadata element
> +        _kimchi_set_metadata_node(dom, meta_xml)
> +
> +
> +def _kimchi_get_metadata_node(dom, element):
> +    # some other tools will not let libvirt create a persistent
> +    # configuration, just return empty
> +    if not dom.isPersistent():
> +        return ""
> +    xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE)
> +    root = etree.fromstring(xml)
> +    metadata = root.find("metadata")
> +    if metadata is None:
>           return ""
> +    tag = "{%s%s}%s" % (KIMCHI_META_URL, element, element)
> +    elem = metadata.find(tag)
> +    #remove the "kimchi" prifix of xml
> +    if elem is not None:
> +        for child in elem.getiterator():
> +            i = child.tag.find('}')
> +            if i >= 0:
> +                child.tag = child.tag[i+1:]
> +        objectify.deannotate(elem, cleanup_namespaces=True)
> +        return etree.tostring(elem)
> +
> +    return ""
> +
> +
> +def get_metadata_node(dom, element, mode="current"):
> +    if CapabilitiesModel().metadata_support:
> +        try:
> +            return dom.metadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT,
> +                                KIMCHI_META_URL + element,
> +                                flags=get_vm_config_flag(dom, mode))
> +        except libvirt.libvirtError:
> +                return ""
> +    else:
> +    # FIXME remove this code when all distro libvirt supports metadata element
> +        return _kimchi_get_metadata_node(dom, element)




More information about the Kimchi-devel mailing list