[Kimchi-devel] [PATCH V5 1/5] Add spice backend support for kimchi

zhoumeina zhoumein at linux.vnet.ibm.com
Mon Jan 13 06:32:56 UTC 2014


Reviewed-by: zhoumeina <zhoumein at linux.vnet.ibm.com>

On 01/10/2014 08:44 PM, apporc wrote:
> 1.  Add spice support for kimchi template
>      Now we can specify a spice parameter when creating a template and updating it.
>
> 2.  Add spice support for kimchi vm
>      When creating a vm, we have a chance to change the graphics configuration to override
>      the value from the template.
>
> 3.  Expose the real port for vnc/spice, so that users can connect vm with popular
>      vnc/spice client tool.
>
> 4.  Spice-vdagent support is added too, so that when users happended to install
>      spice-tool/spice-vdagent in their vm, they will get improved spice graphics effect immediately.
>
> 5.  Specifying graphics parameters when updating vm is not supported yet, it will be added separately
>      in another patch.
>
> Signed-off-by: apporc <appleorchard2000 at gmail.com>
> ---
>   src/kimchi/control/templates.py |    6 ++++--
>   src/kimchi/control/vms.py       |    4 +++-
>   src/kimchi/model.py             |   34 +++++++++++++++++++++-------------
>   src/kimchi/osinfo.py            |    7 ++++---
>   src/kimchi/vmtemplate.py        |   31 +++++++++++++++++++++++++++++--
>   5 files changed, 61 insertions(+), 21 deletions(-)
>
> diff --git a/src/kimchi/control/templates.py b/src/kimchi/control/templates.py
> index bf40e2c..a77936e 100644
> --- a/src/kimchi/control/templates.py
> +++ b/src/kimchi/control/templates.py
> @@ -35,7 +35,8 @@ class Template(Resource):
>           super(Template, self).__init__(model, ident)
>           self.update_params = ["name", "folder", "icon", "os_distro",
>                                 "storagepool", "os_version", "cpus",
> -                              "memory", "cdrom", "disks", "networks"]
> +                              "memory", "cdrom", "disks", "networks",
> +                              "graphics"]
>           self.uri_fmt = "/templates/%s"
>
>       @property
> @@ -50,4 +51,5 @@ class Template(Resource):
>                   'disks': self.info['disks'],
>                   'storagepool': self.info['storagepool'],
>                   'networks': self.info['networks'],
> -                'folder': self.info.get('folder', [])}
> +                'folder': self.info.get('folder', []),
> +                'graphics': self.info['graphics']}
> diff --git a/src/kimchi/control/vms.py b/src/kimchi/control/vms.py
> index d722920..7843be7 100644
> --- a/src/kimchi/control/vms.py
> +++ b/src/kimchi/control/vms.py
> @@ -53,7 +53,9 @@ class VM(Resource):
>                   'screenshot': self.info['screenshot'],
>                   'icon': self.info['icon'],
>                   'graphics': {'type': self.info['graphics']['type'],
> -                             'port': self.info['graphics']['port']}}
> +                             'listen': self.info['graphics']['listen'],
> +                             'port': self.info['graphics']['port']}
> +                }
>
>
>   class VMScreenShot(Resource):
> diff --git a/src/kimchi/model.py b/src/kimchi/model.py
> index ed613b1..4f4b837 100644
> --- a/src/kimchi/model.py
> +++ b/src/kimchi/model.py
> @@ -503,7 +503,8 @@ class Model(object):
>           info = dom.info()
>           state = Model.dom_state_map[info[0]]
>           screenshot = None
> -        graphics_type, graphics_port = self._vm_get_graphics(name)
> +        graphics_type, graphics_listen, graphics_port = self._vm_get_graphics(name)
> +        graphics_port = graphics_port if state == 'running' else None
>           try:
>               if state == 'running':
>                   screenshot = self.vmscreenshot_lookup(name)
> @@ -536,7 +537,10 @@ class Model(object):
>                   'cpus': info[3],
>                   'screenshot': screenshot,
>                   'icon': icon,
> -                'graphics': {"type": graphics_type, "port": graphics_port}}
> +                'graphics': {"type": graphics_type,
> +                             "listen": graphics_listen,
> +                             "port": graphics_port}
> +                }
>
>       def _vm_get_disk_paths(self, dom):
>           xml = dom.XMLDesc(0)
> @@ -580,21 +584,21 @@ class Model(object):
>           expr = "/domain/devices/graphics/@type"
>           res = xmlutils.xpath_get_text(xml, expr)
>           graphics_type = res[0] if res else None
> -        port = None
> +        expr = "/domain/devices/graphics/@listen"
> +        res = xmlutils.xpath_get_text(xml, expr)
> +        graphics_listen = res[0] if res else None
> +        graphics_port = None
>           if graphics_type:
>               expr = "/domain/devices/graphics[@type='%s']/@port" % graphics_type
>               res = xmlutils.xpath_get_text(xml, expr)
> -            port = int(res[0]) if res else None
> -        # FIX ME
> -        # graphics_type should be 'vnc' or None.  'spice' should only be
> -        # returned if we support it in the future.
> -        graphics_type = None if graphics_type != "vnc" else graphics_type
> -        return graphics_type, port
> +            graphics_port = int(res[0]) if res else None
> +        return graphics_type, graphics_listen, graphics_port
>
>       def vm_connect(self, name):
> -        graphics, port = self._vm_get_graphics(name)
> -        if graphics == "vnc" and port != None:
> -            vnc.add_proxy_token(name, port)
> +        graphics_type, graphics_listen, graphics_port \
> +            = self._vm_get_graphics(name)
> +        if graphics_port is not None:
> +            vnc.add_proxy_token(name, graphics_port)
>           else:
>               raise OperationFailed("Only able to connect to running vm's vnc "
>                                     "graphics.")
> @@ -628,8 +632,12 @@ class Model(object):
>                   session.store('vm', vm_uuid, {'icon': icon})
>
>           libvirt_stream = False if len(self.libvirt_stream_protocols) == 0 else True
> +        graphics = params.get('graphics')
>
> -        xml = t.to_vm_xml(name, vm_uuid, libvirt_stream, self.qemu_stream_dns)
> +        xml = t.to_vm_xml(name, vm_uuid,
> +                          libvirt_stream=libvirt_stream,
> +                          qemu_stream_dns=self.qemu_stream_dns,
> +                          graphics=graphics)
>           try:
>               dom = conn.defineXML(xml.encode('utf-8'))
>           except libvirt.libvirtError as e:
> diff --git a/src/kimchi/osinfo.py b/src/kimchi/osinfo.py
> index 0509622..f92db3d 100644
> --- a/src/kimchi/osinfo.py
> +++ b/src/kimchi/osinfo.py
> @@ -73,8 +73,9 @@ isolinks = {
>
>   defaults = {'networks': ['default'],
>               'storagepool': '/storagepools/default',
> -            'domain': 'kvm', 'arch': os.uname()[4]
> -}
> +            'domain': 'kvm', 'arch': os.uname()[4],
> +            'graphics': {'type': 'vnc', 'listen': '0.0.0.0'}}
> +
>
>
>   def _get_arch():
> @@ -90,7 +91,7 @@ def lookup(distro, version):
>       'defaults' and merging the parameters given for the identified OS.  If
>       known, a link to a remote install CD is added.
>       """
> -    params = copy.copy(defaults)
> +    params = copy.deepcopy(defaults)
>       params['os_distro'] = distro
>       params['os_version'] = version
>       params['cdrom'] = isolinks.get(distro, {}).get(version, '')
> diff --git a/src/kimchi/vmtemplate.py b/src/kimchi/vmtemplate.py
> index 6587bbb..58147e3 100644
> --- a/src/kimchi/vmtemplate.py
> +++ b/src/kimchi/vmtemplate.py
> @@ -76,6 +76,11 @@ class VMTemplate(object):
>           self.info.update(entry)
>
>           # Override with the passed in parameters
> +        graph_args = args.get('graphics')
> +        if graph_args:
> +            graphics = dict(self.info['graphics'])
> +            graphics.update(graph_args)
> +            args['graphics'] = graphics
>           self.info.update(args)
>
>       def _get_cdrom_xml(self, libvirt_stream, qemu_stream_dns):
> @@ -157,6 +162,24 @@ class VMTemplate(object):
>               """ % params
>           return ret
>
> +    def _get_graphics_xml(self, params):
> +        graphics_xml = """
> +            <graphics type='%(type)s' autoport='yes' listen='%(listen)s'>
> +            </graphics>
> +        """
> +        spicevmc_xml = """
> +            <channel type='spicevmc'>
> +              <target type='virtio' name='com.redhat.spice.0'/>
> +            </channel>
> +        """
> +        graphics = dict(self.info['graphics'])
> +        if params:
> +            graphics.update(params)
> +        graphics_xml = graphics_xml % graphics
> +        if graphics['type'] == 'spice':
> +            graphics_xml = graphics_xml + spicevmc_xml
> +        return graphics_xml
> +
>       def to_volume_list(self, vm_uuid):
>           storage_path = self._get_storage_path()
>           ret = []
> @@ -198,7 +221,7 @@ class VMTemplate(object):
>               networks += network % net_info
>           return networks
>
> -    def to_vm_xml(self, vm_name, vm_uuid, libvirt_stream = False, qemu_stream_dns = False):
> +    def to_vm_xml(self, vm_name, vm_uuid, **kwargs):
>           params = dict(self.info)
>           params['name'] = vm_name
>           params['uuid'] = vm_uuid
> @@ -207,7 +230,11 @@ class VMTemplate(object):
>           params['qemu-namespace'] = ''
>           params['cdroms'] = ''
>           params['qemu-stream-cmdline'] = ''
> +        graphics = kwargs.get('graphics')
> +        params['graphics'] = self._get_graphics_xml(graphics)
>
> +        qemu_stream_dns = kwargs.get('qemu_stream_dns', False)
> +        libvirt_stream = kwargs.get('libvirt_stream', False)
>           cdrom_xml = self._get_cdrom_xml(libvirt_stream, qemu_stream_dns)
>           if not libvirt_stream and params.get('iso_stream', False):
>               params['qemu-namespace'] = QEMU_NAMESPACE
> @@ -238,7 +265,7 @@ class VMTemplate(object):
>               %(disks)s
>               %(cdroms)s
>               %(networks)s
> -            <graphics type='vnc' />
> +            %(graphics)s
>               <sound model='ich6' />
>               <memballoon model='virtio' />
>             </devices>




More information about the Kimchi-devel mailing list