[Kimchi-devel] [PATCh V12 4/7] manually manage the metadata element
Aline Manera
alinefm at linux.vnet.ibm.com
Wed Apr 30 18:30:47 UTC 2014
On 04/29/2014 12:45 PM, 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 | 88 ++++++++++++++++++++++++++++++++++++++++-------
> 1 file changed, 75 insertions(+), 13 deletions(-)
>
> diff --git a/src/kimchi/model/utils.py b/src/kimchi/model/utils.py
> index 3aaa956..7845c0d 100644
> --- a/src/kimchi/model/utils.py
> +++ b/src/kimchi/model/utils.py
> @@ -17,10 +17,12 @@
> # License along with this library; if not, write to the Free Software
> # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>
> +import re
> from kimchi.exception import OperationFailed
> +from kimchi.model.config import CapabilitiesModel
> import libvirt
> from lxml import etree
> -from lxml.builder import E
> +from lxml.builder import E, ElementMaker
>
>
> KIMCHI_META_URL = "https://github.com/kimchi-project/kimchi"
> @@ -37,6 +39,15 @@ def get_vm_name(vm_name, t_name, name_list):
> raise OperationFailed("KCHUTILS0003E")
>
> +def create_metadata_node(tag):
> + if CapabilitiesModel().metadata_support:
> + return E(tag)
> + else:
> + EM = ElementMaker(namespace=KIMCHI_META_URL,
> + nsmap={KIMCHI_NAMESPACE: KIMCHI_META_URL})
> + return EM(tag)
> +
This function is only used by _kimchi_set_metadata() so we can move the
correct code to there.
I will do that before applying so you don't need to resend the patches
> +
> 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
> @@ -58,6 +69,25 @@ def update_node(root, node):
> return root
>
>
> +def _kimchi_set_metadata_node(dom, node):
> + # 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)
> + kimchi = root.find("metadata/{%s}kimchi" % KIMCHI_META_URL)
> + kimchi = create_metadata_node("kimchi") if kimchi is None else kimchi
> + update_node(kimchi, node)
> + metadata = root.find("metadata")
> + metadata = E.metadata() if metadata is None else metadata
> + update_node(metadata, kimchi)
> + update_node(root, metadata)
> + dom.connect().defineXML(etree.tostring(root))
> +
> +
> def libvirt_get_kimchi_metadata_node(dom, mode="current"):
> try:
> xml = dom.metadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT,
> @@ -69,21 +99,53 @@ def libvirt_get_kimchi_metadata_node(dom, mode="current"):
>
>
> def set_metadata_node(dom, node, mode="all"):
> - kimchi = libvirt_get_kimchi_metadata_node(dom, mode)
> - kimchi = E.kimchi() if kimchi is None else kimchi
> -
> - update_node(kimchi, node)
> - kimchi_xml = etree.tostring(kimchi)
> - # 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, kimchi_xml,
> - KIMCHI_NAMESPACE, KIMCHI_META_URL,
> - flags=get_vm_config_flag(dom, mode))
> + if CapabilitiesModel().metadata_support:
> + kimchi = libvirt_get_kimchi_metadata_node(dom, mode)
> + kimchi = E.kimchi() if kimchi is None else kimchi
> +
> + update_node(kimchi, node)
> + kimchi_xml = etree.tostring(kimchi)
> + # 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, kimchi_xml,
> + KIMCHI_NAMESPACE, KIMCHI_META_URL,
> + flags=get_vm_config_flag(dom, mode))
> + else:
> + # FIXME remove this code when all distro libvirt supports metadata element
> + _kimchi_set_metadata_node(dom, node)
> +
> +
> +def _kimchi_get_metadata_node(dom, tag):
> + # some other tools will not let libvirt create a persistent
> + # configuration, just return empty
> + if not dom.isPersistent():
> + return None
> + xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE)
> + root = etree.fromstring(xml)
> + kimchi = root.find("metadata/{%s}kimchi" % KIMCHI_META_URL)
> + #remove the "kimchi" prifix of xml
> + # some developers may do not like to remove prefix by children iteration
> + # so here, use re to remove the "kimchi" prefix of xml
> + # and developers please don not define element like this:
> + # <foo attr="foo<kimchi:abcd>foo"></foo>
> + if kimchi is not None:
> + kimchi_xml = etree.tostring(kimchi)
> + ns_pattern = re.compile(" xmlns:.*?=((\".*?\")|('.*?'))")
> + kimchi_xml = ns_pattern.sub("", kimchi_xml)
> + prefix_pattern = re.compile("(?<=<)[^/]*?:|(?<=</).*?:")
> + kimchi_xml = prefix_pattern.sub("", kimchi_xml)
> + return etree.fromstring(kimchi_xml)
> + return None
>
>
> def get_metadata_node(dom, tag, mode="current"):
> - kimchi = libvirt_get_kimchi_metadata_node(dom, mode)
> + if CapabilitiesModel().metadata_support:
> + kimchi = libvirt_get_kimchi_metadata_node(dom, mode)
> + else:
> + # FIXME remove this code when all distro libvirt supports metadata element
> + kimchi = _kimchi_get_metadata_node(dom, tag)
> +
> if kimchi is not None:
> node = kimchi.find(tag)
> if node is not None:
More information about the Kimchi-devel
mailing list