[Kimchi-devel] [PATCH] Bug fix #463: Allow add networks with non-ASCII characters to template and guest

Royce Lv lvroyce at linux.vnet.ibm.com
Thu Dec 11 06:40:57 UTC 2014


Reviewed-by: Royce Lv<lvroyce at linux.vnet.ibm.com>
On 2014年12月11日 02:29, Aline Manera wrote:
> Kimchi uses unicode internally but libvirt stores its data encoded with
> utf-8. So we also need to encode the given value to utf-8 to compare it
> properly to libvirt results.
> Also add test cases to cover this scenario.
>
> Signed-off-by: Aline Manera <alinefm at linux.vnet.ibm.com>
> ---
>   src/kimchi/model/networks.py  |  4 ++--
>   src/kimchi/model/templates.py |  6 +++---
>   src/kimchi/model/vmifaces.py  |  1 +
>   src/kimchi/vmtemplate.py      |  4 ++--
>   src/kimchi/xmlutils/utils.py  |  9 ++++++++-
>   tests/test_model.py           | 21 ++++++++++++++++++++-
>   6 files changed, 36 insertions(+), 9 deletions(-)
>
> diff --git a/src/kimchi/model/networks.py b/src/kimchi/model/networks.py
> index f3ea099..1e94fd2 100644
> --- a/src/kimchi/model/networks.py
> +++ b/src/kimchi/model/networks.py
> @@ -293,8 +293,8 @@ class NetworkModel(object):
>           conn = self.conn.get()
>           for dom in conn.listAllDomains(0):
>               networks = self._vm_get_networks(dom)
> -            if network in networks and (state is None or
> -                                        state == dom.state(0)[0]):
> +            if network.encode('utf-8') in networks and \
> +               (state is None or state == dom.state(0)[0]):
>                   vms.append(dom.name())
>           return vms
>   
> diff --git a/src/kimchi/model/templates.py b/src/kimchi/model/templates.py
> index 2ca80ba..85f0839 100644
> --- a/src/kimchi/model/templates.py
> +++ b/src/kimchi/model/templates.py
> @@ -83,7 +83,7 @@ class TemplatesModel(object):
>   
>           for net_name in params.get(u'networks', []):
>               try:
> -                conn.networkLookupByName(net_name)
> +                conn.networkLookupByName(net_name.encode('utf-8'))
>               except Exception:
>                   raise InvalidParameter("KCHTMPL0003E", {'network': net_name,
>                                                           'template': name})
> @@ -200,7 +200,7 @@ class TemplateModel(object):
>   
>           for net_name in params.get(u'networks', []):
>               try:
> -                conn.networkLookupByName(net_name)
> +                conn.networkLookupByName(net_name.encode('utf-8'))
>               except Exception:
>                   raise InvalidParameter("KCHTMPL0003E", {'network': net_name,
>                                                           'template': name})
> @@ -260,7 +260,7 @@ class LibvirtVMTemplate(VMTemplate):
>           for name in names:
>               try:
>                   conn = self.conn.get()
> -                network = conn.networkLookupByName(name)
> +                network = conn.networkLookupByName(name.encode('utf-8'))
>               except libvirt.libvirtError:
>                   raise InvalidParameter("KCHTMPL0003E", {'network': name,
>                                                           'template': self.name})
> diff --git a/src/kimchi/model/vmifaces.py b/src/kimchi/model/vmifaces.py
> index 1206cde..0c10fa9 100644
> --- a/src/kimchi/model/vmifaces.py
> +++ b/src/kimchi/model/vmifaces.py
> @@ -42,6 +42,7 @@ class VMIfacesModel(object):
>       def create(self, vm, params):
>           conn = self.conn.get()
>           networks = conn.listNetworks() + conn.listDefinedNetworks()
> +        networks = map(lambda x: x.decode('utf-8'), networks)
>   
>           if params["type"] == "network" and params["network"] not in networks:
>               raise InvalidParameter("KCHVMIF0002E",
> diff --git a/src/kimchi/vmtemplate.py b/src/kimchi/vmtemplate.py
> index 8582d48..5e4a6a8 100644
> --- a/src/kimchi/vmtemplate.py
> +++ b/src/kimchi/vmtemplate.py
> @@ -184,7 +184,7 @@ class VMTemplate(object):
>   
>               disks_xml += get_disk_xml(params)[1]
>   
> -        return disks_xml
> +        return unicode(disks_xml, 'utf-8')
>   
>       def to_volume_list(self, vm_uuid):
>           storage_path = self._get_storage_path()
> @@ -232,7 +232,7 @@ class VMTemplate(object):
>               networks += get_iface_xml(params, self.info['arch'],
>                                         self.info['os_distro'],
>                                         self.info['os_version'])
> -        return networks
> +        return unicode(networks, 'utf-8')
>   
>       def _get_input_output_xml(self):
>           sound = """
> diff --git a/src/kimchi/xmlutils/utils.py b/src/kimchi/xmlutils/utils.py
> index 4863bb5..be08a14 100644
> --- a/src/kimchi/xmlutils/utils.py
> +++ b/src/kimchi/xmlutils/utils.py
> @@ -23,7 +23,14 @@ from lxml import objectify
>   
>   def xpath_get_text(xml, expr):
>       doc = ET.fromstring(xml)
> -    res = [x.text if not isinstance(x, str) else x for x in doc.xpath(expr)]
> +
> +    res = []
> +    for x in doc.xpath(expr):
> +        if isinstance(x, unicode):
> +            x = x.encode('utf-8')
> +        elif not isinstance(x, str):
> +            x = x.text
> +        res.append(x)
>       return res
>   
>   
> diff --git a/tests/test_model.py b/tests/test_model.py
> index aa2a1bb..acaa711 100644
> --- a/tests/test_model.py
> +++ b/tests/test_model.py
> @@ -889,6 +889,17 @@ class ModelTests(unittest.TestCase):
>                           'subnet': '127.0.100.0/24'}
>               inst.networks_create(net_args)
>               rollback.prependDefer(inst.network_delete, net_name)
> +            inst.network_activate(net_name)
> +            rollback.prependDefer(inst.network_deactivate, net_name)
> +
> +            net_name = u'kīмсhī-пet'
> +            net_args = {'name': net_name,
> +                        'connection': 'nat',
> +                        'subnet': '127.0.20.0/24'}
> +            inst.networks_create(net_args)
> +            rollback.prependDefer(inst.network_delete, net_name)
> +            inst.network_activate(net_name)
> +            rollback.prependDefer(inst.network_deactivate, net_name)
>   
>               orig_params = {'name': 'test', 'memory': 1024, 'cpus': 1,
>                              'cdrom': self.kimchi_iso}
> @@ -908,7 +919,7 @@ class ModelTests(unittest.TestCase):
>               self.assertEquals("default", info["networks"][0])
>   
>               params = {'name': 'new-test', 'memory': 1024, 'cpus': 1,
> -                      'networks': ['default', 'test-network']}
> +                      'networks': ['default', 'test-network', u'kīмсhī-пet']}
>               inst.template_update('new-test', params)
>               info = inst.template_lookup('new-test')
>               for key in params.keys():
> @@ -932,6 +943,14 @@ class ModelTests(unittest.TestCase):
>               self.assertRaises(InvalidParameter, inst.template_update,
>                                 'new-test', params)
>   
> +            params = {'name': 'some-vm', 'template': '/templates/new-test'}
> +            self.assertEquals('some-vm', inst.vms_create(params))
> +            rollback.prependDefer(inst.vm_delete, 'some-vm')
> +
> +            iface_args = {'type': 'network', 'network': u'kīмсhī-пet'}
> +            mac = inst.vmifaces_create('some-vm', iface_args)
> +            self.assertEquals(17, len(mac))
> +
>       def test_vm_edit(self):
>           config.set("authentication", "method", "pam")
>           inst = model.Model(None,




More information about the Kimchi-devel mailing list