[libvirt] [test-API][PATCH 1/2] Add support for spice graphics

* utils/Python/xmlgenerator.py: This extends graphics element for spice XML composing, and support sub-elements settings for audio, images, streaming and so on: <graphics type='spice' autoport='yes'> <image compression='auto_glz'/> <jpeg compression='auto'/> <zlib compression='auto'/> <playback compression='on'/> <streaming mode='filter'/> <clipboard copypaste='no'/> </graphics> * utils/Python/xmlbuilder.py: Add 2 methods add_graphics() and build_graphics() to XmlBuilder class. --- utils/Python/xmlbuilder.py | 36 +++++++++++++++++++++++- utils/Python/xmlgenerator.py | 62 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 91 insertions(+), 7 deletions(-) diff --git a/utils/Python/xmlbuilder.py b/utils/Python/xmlbuilder.py index 5a0f8c8..739eccb 100644 --- a/utils/Python/xmlbuilder.py +++ b/utils/Python/xmlbuilder.py @@ -64,6 +64,13 @@ class XmlBuilder: hostdev_node, domain.getElementsByTagName("console")[0]) return hostdev + def add_graphics(self, params, domain): + graphics = xmlgenerator.graphics_xml(params) + graphics_node = domain.importNode(graphics.childNodes[0], True) + domain.getElementsByTagName("devices")[0].insertBefore( + graphics_node, domain.getElementsByTagName("console")[0]) + return graphics + def build_domain_install(self, params): domain = xmlgenerator.domain_xml(params, True) self.add_disk(params, domain) @@ -151,6 +158,12 @@ class XmlBuilder: self.write_toxml(hostdev) return hostdev.toxml() + def build_graphics(self, params): + graphics = xmlgenerator.graphics_xml(params) + if __DEBUG__: + self.write_toxml(graphics) + return graphics.toxml() + def build_pool(self, params): pool = xmlgenerator.pool_xml(params) if __DEBUG__: @@ -242,6 +255,20 @@ if __name__ == "__main__": interfacexml = xmlobj.build_interface(params) + #-------------------------- + # get graphics xml string + #-------------------------- + print '=' * 30, 'graphics xml', '=' * 30 + params['graphtype'] = 'spice' + params['image'] = 'auto_glz' + params['jpeg'] = 'auto' + params['zlib'] = 'auto' + params['playback'] = 'on' + params['streaming'] = 'filter' + params['clipboard'] = 'no' + + graphicsxml = xmlobj.build_graphics(params) + #--------------------- # get pool xml string #--------------------- @@ -297,6 +324,13 @@ if __name__ == "__main__": params['memory'] = '1048576' params['vcpu'] = '2' params['inputbus'] = 'usb' + params['graphtype'] = 'spice' + params['image'] = 'auto_glz' + params['jpeg'] = 'auto' + params['zlib'] = 'auto' + params['playback'] = 'on' + params['streaming'] = 'filter' + params['clipboard'] = 'no' params['sound'] = 'ac97' params['bootcd'] = '/iso/rhel5.iso' @@ -367,7 +401,7 @@ if __name__ == "__main__": #---------------------------------------- # get domain snapshot xml string #---------------------------------------- - params['name'] = 'hello' + params['snapshotname'] = 'hello' params['description'] = 'hello snapshot' snapshot_xml = xmlobj.build_domain_snapshot(params) diff --git a/utils/Python/xmlgenerator.py b/utils/Python/xmlgenerator.py index d57dd33..460f2e5 100644 --- a/utils/Python/xmlgenerator.py +++ b/utils/Python/xmlgenerator.py @@ -233,12 +233,6 @@ def domain_xml(params, install = False): input_element.setAttribute('bus', 'ps2') devices_element.appendChild(input_element) - # <graphics> - graphics_element = domain.createElement('graphics') - graphics_element.setAttribute('type', 'vnc') - graphics_element.setAttribute('port', '-1') - graphics_element.setAttribute('keymap', 'en-us') - devices_element.appendChild(graphics_element) domain_element.appendChild(devices_element) # <sound> @@ -253,6 +247,62 @@ def domain_xml(params, install = False): return domain +def graphics_xml(params): + graphics = xml.dom.minidom.Document() + # <graphics> + graphics_element = graphics.createElement('graphics') + if not params.has_key('graphtype'): + params['graphtype'] == 'vnc' + + graphics_element.setAttribute('type', params['graphtype']) + graphics.appendChild(graphics_element) + + if params['graphtype'] == 'vnc': + graphics_element.setAttribute('port', '-1') + graphics_element.setAttribute('keymap', 'en-us') + elif params['graphtype'] == 'spice': + graphics_element.setAttribute('autoport', 'yes') + if params.has_key('image'): + image_element = graphics.createElement('image') + # image to set image compression (accepts + # auto_glz, auto_lz, quic, glz, lz, off) + image_element.setAttribute('compression', params['image']) + graphics_element.appendChild(image_element) + if params.has_key('jpeg'): + jpeg_element = graphics.createElement('jpeg') + # jpeg for JPEG compression for images over wan (accepts + # auto, never, always) + jpeg_element.setAttribute('compression', params['jpeg']) + graphics_element.appendChild(jpeg_element) + if params.has_key('zlib'): + zlib_element = graphics.createElement('zlib') + # zlib for configuring wan image compression (accepts + # auto, never, always) + zlib_element.setAttribute('compression', params['zlib']) + graphics_element.appendChild(zlib_element) + if params.has_key('playback'): + playback_element = graphics.createElement('playback') + # playback for enabling audio stream compression (accepts on or off) + playback_element.setAttribute('compression', params['playback']) + graphics_element.appendChild(playback_element) + if params.has_key('streaming'): + streaming_element = graphics.createElement('streaming') + # streamming for settings it's mode attribute to one of + # filter, all or off + streaming_element.setAttribute('mode', params['streaming']) + graphics_element.appendChild(streaming_element) + if params.has_key('clipboard'): + clipboard_element = graphics.createElement('clipboard') + # Copy & Paste functionality is enabled by default, and can + # be disabled by setting the copypaste property to no + clipboard_element.setAttribute('copypaste', params['clipboard']) + graphics_element.appendChild(clipboard_element) + else: + print 'Wrong graphics type was specified.' + sys.exit(1) + + return graphics + def disk_xml(params, cdrom = False): disk = xml.dom.minidom.Document() # <disk> -- START -- 1.7.4.4

* repos/domain/spice_options.py: add this test for BZ#682237 --- repos/domain/spice_options.py | 138 +++++++++++++++++++++++++++++++++++++++++ 1 files changed, 138 insertions(+), 0 deletions(-) create mode 100644 repos/domain/spice_options.py diff --git a/repos/domain/spice_options.py b/repos/domain/spice_options.py new file mode 100644 index 0000000..7e0b027 --- /dev/null +++ b/repos/domain/spice_options.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python +"""For configuring spice compression options testing + domain:spice_options + guestname + xxx + image + auto_glz|auto_lz|quic|glz|lz|off + jpeg + auto|never|always + zlib + auto|never|always + playback + on|off +""" + +__author__ = 'Nan Zhang: nzhang@redhat.com' +__date__ = 'Thu Sep 8, 2011' +__version__ = '0.1.0' +__credits__ = 'Copyright (C) 2011 Red Hat, Inc.' +__all__ = ['usage', 'spice_config'] + +import os +import re +import sys +from xml.dom import minidom + +def append_path(path): + """Append root path of package""" + if path in sys.path: + pass + else: + sys.path.append(path) + +pwd = os.getcwd() +result = re.search('(.*)libvirt-test-API', pwd) +append_path(result.group(0)) + +from lib import connectAPI +from lib import domainAPI +from utils.Python import utils +from utils.Python import xmlbuilder +from exception import LibvirtAPI + +def check_params(params): + """Verify inputing parameter dictionary""" + logger = params['logger'] + keys = ['guestname', 'image', 'jpeg', 'zlib', 'playback'] + for key in keys: + if key not in params: + logger.error("%s is required" %key) + return 1 + return 0 + +def spice_options(params): + """check spice options""" + # Initiate and check parameters + params_check_result = check_params(params) + if params_check_result: + return 1 + logger = params['logger'] + guestname = params['guestname'] + image = params['image'] + jpeg = params['jpeg'] + zlib = params['zlib'] + playback = params['playback'] + + # Connect to local hypervisor connection URI + util = utils.Utils() + uri = util.get_uri('127.0.0.1') + conn = connectAPI.ConnectAPI() + virconn = conn.open(uri) + + caps = conn.get_caps() + logger.debug(caps) + + # Get domain xml + domobj = domainAPI.DomainAPI(virconn) + try: + if guestname not in domobj.get_defined_list(): + logger.error("%s doesn't exist or in running state." % guestname) + return 1 + except LibvirtAPI, e: + logger.error("API error message: %s, error code is %s" % + (e.response()['message'], e.response()['code'])) + return 1 + + guestxml = domobj.get_xml_desc(guestname) + guestobj = minidom.parseString(guestxml) + xmlobj = xmlbuilder.XmlBuilder() + xmlobj.add_graphics(params, guestobj) + guestxml = xmlobj.build_domain(guestobj) + + try: + domobj.undefine(guestname) + domobj.define(guestxml) + domobj.start(guestname) + except LibvirtAPI, e: + logger.error("API error message: %s, error code is %s" % + (e.response()['message'], e.response()['code'])) + return 1 + + xmlobj = domobj.get_xml_desc(guestname) + prexml = xmlobj.split('\n') + postxml = '' + for i in range(len(prexml)): + postxml = postxml + prexml[i].lstrip() + domxml = minidom.parseString(postxml) + + # Check spice options in 'graphcis' tag + graphTag = domxml.getElementsByTagName("graphics") + try: + try: + for graphTag in domxml.getElementsByTagName("graphics"): + assert len(graphTag.childNodes) == 4 + assert graphTag.childNodes[0].getAttribute("compression") \ + == params['image'] + assert graphTag.childNodes[1].getAttribute("compression") \ + == params['jpeg'] + assert graphTag.childNodes[2].getAttribute("compression") \ + == params['zlib'] + assert graphTag.childNodes[3].getAttribute("compression") \ + == params['playback'] + except AssertionError: + logger.error("Wrong checks happend on spice options.") + conn.close() + logger.info("closed hypervisor connection") + return 1 + finally: + logger.info("spice options were checked successfully.") + conn.close() + logger.info("closed hypervisor connection") + + return 0 + +def spice_options_clean(): + """Clean testing environment""" + pass + -- 1.7.4.4

On 2011年09月29日 17:30, Nan Zhang wrote:
* repos/domain/spice_options.py: add this test for BZ#682237 --- repos/domain/spice_options.py | 138 +++++++++++++++++++++++++++++++++++++++++ 1 files changed, 138 insertions(+), 0 deletions(-) create mode 100644 repos/domain/spice_options.py
diff --git a/repos/domain/spice_options.py b/repos/domain/spice_options.py new file mode 100644 index 0000000..7e0b027 --- /dev/null +++ b/repos/domain/spice_options.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python +"""For configuring spice compression options testing + domain:spice_options + guestname + xxx + image + auto_glz|auto_lz|quic|glz|lz|off + jpeg + auto|never|always + zlib + auto|never|always + playback + on|off +"""
Wondering if the spice graphic testing should be packed with vnc graphic testing together, i.e. A single API for graphics testing, so we don't have to expose more and more APIs for testing conf in future.
+ +__author__ = 'Nan Zhang: nzhang@redhat.com' +__date__ = 'Thu Sep 8, 2011' +__version__ = '0.1.0' +__credits__ = 'Copyright (C) 2011 Red Hat, Inc.' +__all__ = ['usage', 'spice_config'] + +import os +import re +import sys +from xml.dom import minidom + +def append_path(path): + """Append root path of package""" + if path in sys.path: + pass + else: + sys.path.append(path) + +pwd = os.getcwd() +result = re.search('(.*)libvirt-test-API', pwd) +append_path(result.group(0)) + +from lib import connectAPI +from lib import domainAPI +from utils.Python import utils +from utils.Python import xmlbuilder +from exception import LibvirtAPI + +def check_params(params): + """Verify inputing parameter dictionary""" + logger = params['logger'] + keys = ['guestname', 'image', 'jpeg', 'zlib', 'playback'] + for key in keys: + if key not in params: + logger.error("%s is required" %key) + return 1 + return 0 + +def spice_options(params): + """check spice options""" + # Initiate and check parameters + params_check_result = check_params(params) + if params_check_result: + return 1 + logger = params['logger'] + guestname = params['guestname'] + image = params['image'] + jpeg = params['jpeg'] + zlib = params['zlib'] + playback = params['playback'] + + # Connect to local hypervisor connection URI + util = utils.Utils() + uri = util.get_uri('127.0.0.1') + conn = connectAPI.ConnectAPI() + virconn = conn.open(uri) + + caps = conn.get_caps() + logger.debug(caps) + + # Get domain xml + domobj = domainAPI.DomainAPI(virconn) + try: + if guestname not in domobj.get_defined_list(): + logger.error("%s doesn't exist or in running state." % guestname) + return 1 + except LibvirtAPI, e: + logger.error("API error message: %s, error code is %s" % + (e.response()['message'], e.response()['code'])) + return 1 + + guestxml = domobj.get_xml_desc(guestname) + guestobj = minidom.parseString(guestxml) + xmlobj = xmlbuilder.XmlBuilder() + xmlobj.add_graphics(params, guestobj) + guestxml = xmlobj.build_domain(guestobj) + + try: + domobj.undefine(guestname)
You don't need the undefine() here actually, a define on an existed domain will just re-define the domain config.
+ domobj.define(guestxml)
I even think you shouldn't invoke define(), start() here, what you need to do is just generating the graphic XML and insert it into the domain xml. Other left work should be done by other public APIs we already have. And after that, a specific checking API (if it's need) should be exposed as public API. and thus you use that in testing conf. Writing cases like so is destroying the design pricinple of test-API.
+ domobj.start(guestname) + except LibvirtAPI, e: + logger.error("API error message: %s, error code is %s" % + (e.response()['message'], e.response()['code'])) + return 1 + + xmlobj = domobj.get_xml_desc(guestname) + prexml = xmlobj.split('\n') + postxml = '' + for i in range(len(prexml)): + postxml = postxml + prexml[i].lstrip() + domxml = minidom.parseString(postxml) + + # Check spice options in 'graphcis' tag + graphTag = domxml.getElementsByTagName("graphics") + try: + try: + for graphTag in domxml.getElementsByTagName("graphics"): + assert len(graphTag.childNodes) == 4 + assert graphTag.childNodes[0].getAttribute("compression") \ + == params['image'] + assert graphTag.childNodes[1].getAttribute("compression") \ + == params['jpeg'] + assert graphTag.childNodes[2].getAttribute("compression") \ + == params['zlib'] + assert graphTag.childNodes[3].getAttribute("compression") \ + == params['playback']
This is an aditional constraints which is not in libvirt's domain XML. With this codes, the first child node must be image? and likewise for other child nodes. It just assumes libvirt will always outputs in the fixed sequence for this child nodes, though indeed libvirt unlikely change the sequence for campatibility, it still not a good idea.
+ except AssertionError: + logger.error("Wrong checks happend on spice options.") + conn.close() + logger.info("closed hypervisor connection") + return 1 + finally: + logger.info("spice options were checked successfully.") + conn.close() + logger.info("closed hypervisor connection") + + return 0 + +def spice_options_clean(): + """Clean testing environment""" + pass +
So, IMHO the right way to go is: 1) A single public API for graphic testing, regardless of what the graphic type is. This allow us have a unified API without considering future graphic types. 2) A public API for accepting the configurations from user, and generate the graphics XML. 3) A public API for inserting XML into the domain XML. As far as I known, there is still no API for inserting XML. Per in the testing world, you will want to insert XML from time to time, a common API will definitely save the life. 4) your checking method as a public API, without introducing the additional constraints. In other words, the pricinple is to keep every API's work independant enough. And thus you don't have to care about how the user will write the testing conf. This is what we do for virsh-rail too. Though it might be big effort to do like so in test-API currently, it already went some distance away from the original design. Regards, Osier

Sorry, the mail subject is missing some words, the whole should be: [libvirt] [test-API][PATCH 1/2] Add support for spice graphics type in xml test module On 09/29/2011 05:30 PM, Nan Zhang wrote:
* utils/Python/xmlgenerator.py: This extends graphics element for spice XML composing, and support sub-elements settings for audio, images, streaming and so on:
<graphics type='spice' autoport='yes'> <image compression='auto_glz'/> <jpeg compression='auto'/> <zlib compression='auto'/> <playback compression='on'/> <streaming mode='filter'/> <clipboard copypaste='no'/> </graphics>
* utils/Python/xmlbuilder.py: Add 2 methods add_graphics() and build_graphics() to XmlBuilder class. --- utils/Python/xmlbuilder.py | 36 +++++++++++++++++++++++- utils/Python/xmlgenerator.py | 62 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 91 insertions(+), 7 deletions(-)
diff --git a/utils/Python/xmlbuilder.py b/utils/Python/xmlbuilder.py index 5a0f8c8..739eccb 100644 --- a/utils/Python/xmlbuilder.py +++ b/utils/Python/xmlbuilder.py @@ -64,6 +64,13 @@ class XmlBuilder: hostdev_node, domain.getElementsByTagName("console")[0]) return hostdev
+ def add_graphics(self, params, domain): + graphics = xmlgenerator.graphics_xml(params) + graphics_node = domain.importNode(graphics.childNodes[0], True) + domain.getElementsByTagName("devices")[0].insertBefore( + graphics_node, domain.getElementsByTagName("console")[0]) + return graphics + def build_domain_install(self, params): domain = xmlgenerator.domain_xml(params, True) self.add_disk(params, domain) @@ -151,6 +158,12 @@ class XmlBuilder: self.write_toxml(hostdev) return hostdev.toxml()
+ def build_graphics(self, params): + graphics = xmlgenerator.graphics_xml(params) + if __DEBUG__: + self.write_toxml(graphics) + return graphics.toxml() + def build_pool(self, params): pool = xmlgenerator.pool_xml(params) if __DEBUG__: @@ -242,6 +255,20 @@ if __name__ == "__main__":
interfacexml = xmlobj.build_interface(params)
+ #-------------------------- + # get graphics xml string + #-------------------------- + print '=' * 30, 'graphics xml', '=' * 30 + params['graphtype'] = 'spice' + params['image'] = 'auto_glz' + params['jpeg'] = 'auto' + params['zlib'] = 'auto' + params['playback'] = 'on' + params['streaming'] = 'filter' + params['clipboard'] = 'no' + + graphicsxml = xmlobj.build_graphics(params) + #--------------------- # get pool xml string #--------------------- @@ -297,6 +324,13 @@ if __name__ == "__main__": params['memory'] = '1048576' params['vcpu'] = '2' params['inputbus'] = 'usb' + params['graphtype'] = 'spice' + params['image'] = 'auto_glz' + params['jpeg'] = 'auto' + params['zlib'] = 'auto' + params['playback'] = 'on' + params['streaming'] = 'filter' + params['clipboard'] = 'no' params['sound'] = 'ac97' params['bootcd'] = '/iso/rhel5.iso'
@@ -367,7 +401,7 @@ if __name__ == "__main__": #---------------------------------------- # get domain snapshot xml string #---------------------------------------- - params['name'] = 'hello' + params['snapshotname'] = 'hello' params['description'] = 'hello snapshot' snapshot_xml = xmlobj.build_domain_snapshot(params)
diff --git a/utils/Python/xmlgenerator.py b/utils/Python/xmlgenerator.py index d57dd33..460f2e5 100644 --- a/utils/Python/xmlgenerator.py +++ b/utils/Python/xmlgenerator.py @@ -233,12 +233,6 @@ def domain_xml(params, install = False): input_element.setAttribute('bus', 'ps2') devices_element.appendChild(input_element)
- #<graphics> - graphics_element = domain.createElement('graphics') - graphics_element.setAttribute('type', 'vnc') - graphics_element.setAttribute('port', '-1') - graphics_element.setAttribute('keymap', 'en-us') - devices_element.appendChild(graphics_element) domain_element.appendChild(devices_element)
#<sound> @@ -253,6 +247,62 @@ def domain_xml(params, install = False):
return domain
+def graphics_xml(params): + graphics = xml.dom.minidom.Document() + #<graphics> + graphics_element = graphics.createElement('graphics') + if not params.has_key('graphtype'): + params['graphtype'] == 'vnc' + + graphics_element.setAttribute('type', params['graphtype']) + graphics.appendChild(graphics_element) + + if params['graphtype'] == 'vnc': + graphics_element.setAttribute('port', '-1') + graphics_element.setAttribute('keymap', 'en-us') + elif params['graphtype'] == 'spice': + graphics_element.setAttribute('autoport', 'yes') + if params.has_key('image'): + image_element = graphics.createElement('image') + # image to set image compression (accepts + # auto_glz, auto_lz, quic, glz, lz, off) + image_element.setAttribute('compression', params['image']) + graphics_element.appendChild(image_element) + if params.has_key('jpeg'): + jpeg_element = graphics.createElement('jpeg') + # jpeg for JPEG compression for images over wan (accepts + # auto, never, always) + jpeg_element.setAttribute('compression', params['jpeg']) + graphics_element.appendChild(jpeg_element) + if params.has_key('zlib'): + zlib_element = graphics.createElement('zlib') + # zlib for configuring wan image compression (accepts + # auto, never, always) + zlib_element.setAttribute('compression', params['zlib']) + graphics_element.appendChild(zlib_element) + if params.has_key('playback'): + playback_element = graphics.createElement('playback') + # playback for enabling audio stream compression (accepts on or off) + playback_element.setAttribute('compression', params['playback']) + graphics_element.appendChild(playback_element) + if params.has_key('streaming'): + streaming_element = graphics.createElement('streaming') + # streamming for settings it's mode attribute to one of + # filter, all or off + streaming_element.setAttribute('mode', params['streaming']) + graphics_element.appendChild(streaming_element) + if params.has_key('clipboard'): + clipboard_element = graphics.createElement('clipboard') + # Copy& Paste functionality is enabled by default, and can + # be disabled by setting the copypaste property to no + clipboard_element.setAttribute('copypaste', params['clipboard']) + graphics_element.appendChild(clipboard_element) + else: + print 'Wrong graphics type was specified.' + sys.exit(1) + + return graphics + def disk_xml(params, cdrom = False): disk = xml.dom.minidom.Document() #<disk> -- START

On 2011年09月29日 17:30, Nan Zhang wrote:
* utils/Python/xmlgenerator.py: This extends graphics element for spice XML composing, and support sub-elements settings for audio, images, streaming and so on:
<graphics type='spice' autoport='yes'> <image compression='auto_glz'/> <jpeg compression='auto'/> <zlib compression='auto'/> <playback compression='on'/> <streaming mode='filter'/> <clipboard copypaste='no'/> </graphics>
* utils/Python/xmlbuilder.py: Add 2 methods add_graphics() and build_graphics() to XmlBuilder class. --- utils/Python/xmlbuilder.py | 36 +++++++++++++++++++++++- utils/Python/xmlgenerator.py | 62 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 91 insertions(+), 7 deletions(-)
diff --git a/utils/Python/xmlbuilder.py b/utils/Python/xmlbuilder.py index 5a0f8c8..739eccb 100644 --- a/utils/Python/xmlbuilder.py +++ b/utils/Python/xmlbuilder.py @@ -64,6 +64,13 @@ class XmlBuilder: hostdev_node, domain.getElementsByTagName("console")[0]) return hostdev
+ def add_graphics(self, params, domain): + graphics = xmlgenerator.graphics_xml(params) + graphics_node = domain.importNode(graphics.childNodes[0], True) + domain.getElementsByTagName("devices")[0].insertBefore( + graphics_node, domain.getElementsByTagName("console")[0]) + return graphics + def build_domain_install(self, params): domain = xmlgenerator.domain_xml(params, True) self.add_disk(params, domain) @@ -151,6 +158,12 @@ class XmlBuilder: self.write_toxml(hostdev) return hostdev.toxml()
+ def build_graphics(self, params): + graphics = xmlgenerator.graphics_xml(params) + if __DEBUG__: + self.write_toxml(graphics) + return graphics.toxml() + def build_pool(self, params): pool = xmlgenerator.pool_xml(params) if __DEBUG__: @@ -242,6 +255,20 @@ if __name__ == "__main__":
interfacexml = xmlobj.build_interface(params)
+ #-------------------------- + # get graphics xml string + #-------------------------- + print '=' * 30, 'graphics xml', '=' * 30 + params['graphtype'] = 'spice' + params['image'] = 'auto_glz' + params['jpeg'] = 'auto' + params['zlib'] = 'auto' + params['playback'] = 'on' + params['streaming'] = 'filter' + params['clipboard'] = 'no'
What does these hardcoding for?
+ + graphicsxml = xmlobj.build_graphics(params) + #--------------------- # get pool xml string #--------------------- @@ -297,6 +324,13 @@ if __name__ == "__main__": params['memory'] = '1048576' params['vcpu'] = '2' params['inputbus'] = 'usb' + params['graphtype'] = 'spice' + params['image'] = 'auto_glz' + params['jpeg'] = 'auto' + params['zlib'] = 'auto' + params['playback'] = 'on' + params['streaming'] = 'filter' + params['clipboard'] = 'no'
Also these?
params['sound'] = 'ac97' params['bootcd'] = '/iso/rhel5.iso'
@@ -367,7 +401,7 @@ if __name__ == "__main__": #---------------------------------------- # get domain snapshot xml string #---------------------------------------- - params['name'] = 'hello' + params['snapshotname'] = 'hello' params['description'] = 'hello snapshot' snapshot_xml = xmlobj.build_domain_snapshot(params)
diff --git a/utils/Python/xmlgenerator.py b/utils/Python/xmlgenerator.py index d57dd33..460f2e5 100644 --- a/utils/Python/xmlgenerator.py +++ b/utils/Python/xmlgenerator.py @@ -233,12 +233,6 @@ def domain_xml(params, install = False): input_element.setAttribute('bus', 'ps2') devices_element.appendChild(input_element)
- #<graphics> - graphics_element = domain.createElement('graphics') - graphics_element.setAttribute('type', 'vnc') - graphics_element.setAttribute('port', '-1') - graphics_element.setAttribute('keymap', 'en-us') - devices_element.appendChild(graphics_element) domain_element.appendChild(devices_element)
#<sound> @@ -253,6 +247,62 @@ def domain_xml(params, install = False):
return domain
+def graphics_xml(params): + graphics = xml.dom.minidom.Document() + #<graphics> + graphics_element = graphics.createElement('graphics') + if not params.has_key('graphtype'): + params['graphtype'] == 'vnc' + + graphics_element.setAttribute('type', params['graphtype']) + graphics.appendChild(graphics_element) + + if params['graphtype'] == 'vnc': + graphics_element.setAttribute('port', '-1') + graphics_element.setAttribute('keymap', 'en-us') + elif params['graphtype'] == 'spice': + graphics_element.setAttribute('autoport', 'yes') + if params.has_key('image'): + image_element = graphics.createElement('image') + # image to set image compression (accepts + # auto_glz, auto_lz, quic, glz, lz, off) + image_element.setAttribute('compression', params['image']) + graphics_element.appendChild(image_element) + if params.has_key('jpeg'): + jpeg_element = graphics.createElement('jpeg') + # jpeg for JPEG compression for images over wan (accepts + # auto, never, always) + jpeg_element.setAttribute('compression', params['jpeg']) + graphics_element.appendChild(jpeg_element) + if params.has_key('zlib'): + zlib_element = graphics.createElement('zlib') + # zlib for configuring wan image compression (accepts + # auto, never, always) + zlib_element.setAttribute('compression', params['zlib']) + graphics_element.appendChild(zlib_element) + if params.has_key('playback'): + playback_element = graphics.createElement('playback') + # playback for enabling audio stream compression (accepts on or off) + playback_element.setAttribute('compression', params['playback']) + graphics_element.appendChild(playback_element) + if params.has_key('streaming'): + streaming_element = graphics.createElement('streaming') + # streamming for settings it's mode attribute to one of + # filter, all or off + streaming_element.setAttribute('mode', params['streaming']) + graphics_element.appendChild(streaming_element) + if params.has_key('clipboard'): + clipboard_element = graphics.createElement('clipboard') + # Copy& Paste functionality is enabled by default, and can + # be disabled by setting the copypaste property to no + clipboard_element.setAttribute('copypaste', params['clipboard']) + graphics_element.appendChild(clipboard_element) + else: + print 'Wrong graphics type was specified.' + sys.exit(1) + + return graphics +
Others look good. Per comments in previous patch, you might want to give a good name for this function, and expose it as pubic API.
def disk_xml(params, cdrom = False): disk = xml.dom.minidom.Document() #<disk> -- START
participants (2)
-
Nan Zhang
-
Osier Yang