[Kimchi-devel] [PATCH 2/5] Change the way that get_vm() and vm_list() search for VMs

Aline Manera alinefm at linux.vnet.ibm.com
Mon May 4 18:52:18 UTC 2015



On 28/04/2015 10:16, Ramon Medeiros wrote:
> Instead of searching VMs by name, get_vm() and vm_list() will use as
> criteria the title tag to search vms. This is necessary to avoid unicode
> conflicts with libvirt.
>
> Signed-off-by: Ramon Medeiros <ramonn at linux.vnet.ibm.com>
> ---
>   src/kimchi/model/vms.py | 46 ++++++++++++++++++++++++++++++++++++++--------
>   1 file changed, 38 insertions(+), 8 deletions(-)
>
> diff --git a/src/kimchi/model/vms.py b/src/kimchi/model/vms.py
> index c8267c1..6792447 100644
> --- a/src/kimchi/model/vms.py
> +++ b/src/kimchi/model/vms.py
> @@ -150,7 +150,21 @@ class VMsModel(object):
>       @staticmethod
>       def get_vms(conn):
>           conn_ = conn.get()
> -        names = [dom.name().decode('utf-8') for dom in conn_.listAllDomains(0)]
> +
> +        # retrieve title instead of name
> +        names = []
> +        for dom in conn_.listAllDomains(0):
> +

> +            xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE)
> +            root = etree.fromstring(xml)
> +
> +            # machine does not have title: use name
> +            if root.find("title") == None:
> +                names.append(root.find("name").text.decode('utf-8'))
> +                continue
> +

There is some useful XML functions in xmlutils/utils.py
Here you can use xpath_get_text() to get the 'title' value

Something like:

xml = dom.XMLDesc(...)
title = xpath_get_text(xml, '/domain/title')

# title tag is not present
if len(title) == 0:
     names.append(dom.name().decode('utf-8))
else:
     names.append(title[0])

Also you have the libvirt fuction virDomain.name() to get the name 
without needing to parse the XML.



> +            # has title: use it
> +            names.append(root.find("title").text)
>           names = sorted(names, key=unicode.lower)
>           return names
>
> @@ -865,14 +879,30 @@ class VMModel(object):
>       def get_vm(name, conn):
>           conn = conn.get()
>           try:
> -            # outgoing text to libvirt, encode('utf-8')
> -            return conn.lookupByName(name.encode("utf-8"))

> +
> +            for dom in conn.listAllDomains(0):
> +
> +                xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE)
> +                root = etree.fromstring(xml)
> +
> +                # get name
> +                # machine does not have title: use name
> +                if root.find("title") == None:
> +                    vm_name = root.find("name").text
> +                # has title: use it
> +                else:
> +                    vm_name = root.find("title").text
> +
> +                # name match: return dom
> +                if vm_name == name:
> +                    return dom
> +

I don't think you need to parse all the VMs to get the one you are 
looking for.

You received the unicode named with non-ASCII values BUT you know how to 
convert it to get the real name on XML.

So it should be:

non_ascii_name = unicode(name.encode('utf-8'), errors='ignore')
return conn.lookupByName(non_ascii_name)

>           except libvirt.libvirtError as e:
> -            if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
> -                raise NotFoundError("KCHVM0002E", {'name': name})
> -            else:
> -                raise OperationFailed("KCHVM0009E", {'name': name,
> -                                                     'err': e.message})
> +            raise OperationFailed("KCHVM0009E", {'name': name, 'err': e.message})
> +
> +        # not found
> +        raise NotFoundError("KCHVM0002E", {'name': name})
> +
>
>       def delete(self, name):
>           conn = self.conn.get()




More information about the Kimchi-devel mailing list