[Kimchi-devel] [PATCH] Template: Check if the host supports Spice

Aline Manera alinefm at linux.vnet.ibm.com
Tue Mar 25 19:10:14 UTC 2014


Reviewed-by: Aline Manera <alinefm at linux.vnet.ibm.com>

On 03/25/2014 04:53 AM, zhshzhou at linux.vnet.ibm.com wrote:
> From: Zhou Zheng Sheng <zhshzhou at linux.vnet.ibm.com>
>
> On some architecture of hosts, such as ppc64 hosts, QEMU is not compiled
> with Spice. So we'd like to disable Spice on these hosts. Unfortunately
> even QEMU is not compiled with Spice, 'qemu --help' still prints Spice
> related help. In this patch we use ldd to determine if QEMU is linked to
> libspice-server.so, and provide this information through the
> /config/capabilities URI. The front-end code then checks the capabilities
> and add or remove Spice from the graphic options respectively.
>
> Signed-off-by: Zhou Zheng Sheng <zhshzhou at linux.vnet.ibm.com>
> ---
>   docs/API.md                            |  1 +
>   src/kimchi/config.py.in                | 10 +++++++---
>   src/kimchi/mockmodel.py                |  1 +
>   src/kimchi/model/config.py             | 15 ++++++++++++++-
>   tests/test_rest.py                     |  1 +
>   ui/js/src/kimchi.api.js                |  6 ++++--
>   ui/js/src/kimchi.template_edit_main.js | 13 +++++++++++--
>   7 files changed, 39 insertions(+), 8 deletions(-)
>
> diff --git a/docs/API.md b/docs/API.md
> index a380558..3711fbe 100644
> --- a/docs/API.md
> +++ b/docs/API.md
> @@ -573,6 +573,7 @@ creation.
>   * **GET**: Retrieve capabilities information
>       * libvirt_stream_protocols: list of which network protocols are accepted
>         for iso streaming by libvirt
> +    * qemu_spice: True, if QEMU supports Spice; False, otherwise
>       * qemu_stream: True, if QEMU supports ISO streaming; False, otherwise
>       * screenshot: True, if libvirt stream functionality can create screenshot
>         file without problems; False, otherwise or None if the functionality was
> diff --git a/src/kimchi/config.py.in b/src/kimchi/config.py.in
> index cf8497a..d15a6b5 100644
> --- a/src/kimchi/config.py.in
> +++ b/src/kimchi/config.py.in
> @@ -54,15 +54,19 @@ def get_debugreports_path():
>       return os.path.join(paths.state_dir, 'debugreports')
>
>
> -def find_qemu_binary():
> +def find_qemu_binary(find_emulator=False):
>       try:
>           connect = libvirt.open('qemu:///system')
>       except Exception, e:
>           raise Exception("Unable to get qemu binary location: %s" % e)
>       try:
>           xml = connect.getCapabilities()
> -        expr = "/capabilities/guest/arch[@name='%s']\
> -                /domain[@type='kvm']/emulator" % platform.machine()
> +        if find_emulator:
> +            expr = "/capabilities/guest/arch[@name='%s']\
> +                    /emulator" % platform.machine()
> +        else:
> +            expr = "/capabilities/guest/arch[@name='%s']\
> +                    /domain[@type='kvm']/emulator" % platform.machine()
>           res = xpath_get_text(xml, expr)
>           location = res[0]
>       except Exception, e:
> diff --git a/src/kimchi/mockmodel.py b/src/kimchi/mockmodel.py
> index faf1049..7b567cb 100644
> --- a/src/kimchi/mockmodel.py
> +++ b/src/kimchi/mockmodel.py
> @@ -65,6 +65,7 @@ class MockModel(object):
>       def capabilities_lookup(self, *ident):
>           return {'libvirt_stream_protocols':
>                   ['http', 'https', 'ftp', 'ftps', 'tftp'],
> +                'qemu_spice': True,
>                   'qemu_stream': True,
>                   'screenshot': True,
>                   'system_report_tool': True,
> diff --git a/src/kimchi/model/config.py b/src/kimchi/model/config.py
> index a6a25e4..7f553ea 100644
> --- a/src/kimchi/model/config.py
> +++ b/src/kimchi/model/config.py
> @@ -23,6 +23,7 @@ import cherrypy
>
>   from kimchi.basemodel import Singleton
>   from kimchi.config import config as kconfig
> +from kimchi.config import find_qemu_binary
>   from kimchi.distroloader import DistroLoader
>   from kimchi.exception import NotFoundError
>   from kimchi.featuretests import FeatureTests
> @@ -30,7 +31,7 @@ from kimchi.model.debugreports import DebugReportsModel
>   from kimchi.repositories import Repositories
>   from kimchi.screenshot import VMScreenshot
>   from kimchi.swupdate import SoftwareUpdate
> -from kimchi.utils import check_url_path, kimchi_log
> +from kimchi.utils import check_url_path, kimchi_log, run_command
>
>
>   class ConfigModel(object):
> @@ -72,6 +73,17 @@ class CapabilitiesModel(object):
>           kimchi_log.info("*** Feature tests completed ***")
>       _set_capabilities.priority = 90
>
> +    def _qemu_support_spice(self):
> +        qemu_path = find_qemu_binary(find_emulator=True)
> +        out, err, rc = run_command(['ldd', qemu_path])
> +        if rc != 0:
> +            kimchi_log.error('Failed to find qemu binary dependencies: %s', err)
> +            return False
> +        for line in out.split('\n'):
> +            if line.lstrip().startswith('libspice-server.so'):
> +                return True
> +        return False
> +
>       def lookup(self, *ident):
>           report_tool = DebugReportsModel.get_system_report_tool()
>           try:
> @@ -89,6 +101,7 @@ class CapabilitiesModel(object):
>               repo_mngt_tool = repo._pkg_mnger.TYPE
>
>           return {'libvirt_stream_protocols': self.libvirt_stream_protocols,
> +                'qemu_spice': self._qemu_support_spice(),
>                   'qemu_stream': self.qemu_stream,
>                   'screenshot': VMScreenshot.get_stream_test_result(),
>                   'system_report_tool': bool(report_tool),
> diff --git a/tests/test_rest.py b/tests/test_rest.py
> index 3f2e449..ca4eeed 100644
> --- a/tests/test_rest.py
> +++ b/tests/test_rest.py
> @@ -1346,6 +1346,7 @@ class RestTests(unittest.TestCase):
>           conf = json.loads(resp)
>           self.assertIn('libvirt_stream_protocols', conf)
>           self.assertIn('qemu_stream', conf)
> +        self.assertIn('qemu_spice', conf)
>           self.assertIn('screenshot', conf)
>           self.assertIn('system_report_tool', conf)
>           self.assertIn('update_tool', conf)
> diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js
> index 4310435..075b9d0 100644
> --- a/ui/js/src/kimchi.api.js
> +++ b/ui/js/src/kimchi.api.js
> @@ -49,14 +49,16 @@ var kimchi = {
>        * Get host capabilities
>        * suc: callback if succeed err: callback if failed
>        */
> -    getCapabilities : function(suc, err) {
> +    getCapabilities : function(suc, err, done) {
> +        done = typeof done !== 'undefined' ? done: function(){};
>           kimchi.requestJSON({
>               url : "/config/capabilities",
>               type : "GET",
>               contentType : "application/json",
>               dataType : "json",
>               success: suc,
> -            error: err
> +            error: err,
> +            complete: done
>           });
>       },
>
> diff --git a/ui/js/src/kimchi.template_edit_main.js b/ui/js/src/kimchi.template_edit_main.js
> index 58f4506..9c429c4 100644
> --- a/ui/js/src/kimchi.template_edit_main.js
> +++ b/ui/js/src/kimchi.template_edit_main.js
> @@ -30,8 +30,17 @@ kimchi.template_edit_main = function() {
>           }
>           var disks = template.disks;
>           $('input[name="disks"]').val(disks[0].size);
> -        var options = [{label: 'VNC', value: 'vnc'}, {label: 'Spice', value: 'spice'}];
> -        kimchi.select('template-edit-graphics-list', options);
> +
> +        var options = [{label: 'VNC', value: 'vnc'}];
> +        kimchi.getCapabilities(function(result) {
> +            if (result.qemu_spice == true) {
> +                options.push({label: 'Spice', value: 'spice'})
> +            }
> +        }, function() {
> +        }, function(){
> +            kimchi.select('template-edit-graphics-list', options);
> +        });
> +
>           kimchi.listStoragePools(function(result) {
>               var options = [];
>               if (result && result.length) {




More information about the Kimchi-devel mailing list