mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-02-25 18:55:27 -06:00
VirtualGraphics: Switch to new style XML props
This commit is contained in:
parent
f079ec36eb
commit
75e34247f3
@ -27,10 +27,14 @@
|
||||
<graphics type="sdl" xauth="/tmp/.Xauthority" display="1:2"/>
|
||||
<graphics type="rdp"/>
|
||||
<graphics type="vnc" port="-1" socket="/tmp/foobar"/>
|
||||
<graphics type="vnc" autoport="yes"/>
|
||||
<graphics type="spice" passwd="foobar" port="100" tlsPort="101" listen="0.0.0.0" passwdValidTo="2010-04-09T15:51:00">
|
||||
<channel name='inputs' mode='insecure'/>
|
||||
<channel name='main' mode='secure'/>
|
||||
<channel name='record' mode='any'/>
|
||||
<channel name='cursor' mode='any'/>
|
||||
<channel name='playback' mode='any'/>
|
||||
<channel name='display' mode='any'/>
|
||||
</graphics>
|
||||
</devices>
|
||||
<seclabel type="static" model="selinux">
|
||||
|
@ -23,14 +23,18 @@
|
||||
<source dev="/dev/loop0"/>
|
||||
<target dev="fda" bus="fdc"/>
|
||||
</disk>
|
||||
<graphics type="vnc" passwd="newpass" port="6000" listen="1.2.3.4"/>
|
||||
<graphics type="vnc" passwd="newpass" port="6000" listen="1.2.3.4" keymap="en-us"/>
|
||||
<graphics type="sdl" xauth="fooauth" display="6:1"/>
|
||||
<graphics type="rdp"/>
|
||||
<graphics type="vnc"/>
|
||||
<graphics type="vnc" port="-1" socket="/var/lib/libvirt/socket/foo"/>
|
||||
<graphics type="vnc" autoport="no"/>
|
||||
<graphics type="spice" passwd="newpass" port="6000" tlsPort="6001" listen="1.2.3.4" passwdValidTo="2011-01-07T19:08:00">
|
||||
<channel name="inputs" mode="secure"/>
|
||||
<channel name="main" mode="any"/>
|
||||
<channel name="record" mode="insecure"/>
|
||||
<channel name="cursor" mode="any"/>
|
||||
<channel name="playback" mode="insecure"/>
|
||||
<channel name="display" mode="secure"/>
|
||||
</graphics>
|
||||
</devices>
|
||||
<seclabel type="static" model="selinux">
|
||||
|
@ -467,12 +467,14 @@ class XMLParseTest(unittest.TestCase):
|
||||
dev3 = guest.get_devices("graphics")[2]
|
||||
dev4 = guest.get_devices("graphics")[3]
|
||||
dev5 = guest.get_devices("graphics")[4]
|
||||
dev6 = guest.get_devices("graphics")[5]
|
||||
|
||||
check = self._make_checker(dev1)
|
||||
check("type", "vnc")
|
||||
check("passwd", "foobar", "newpass")
|
||||
check("port", 100, 6000)
|
||||
check("listen", "0.0.0.0", "1.2.3.4")
|
||||
check("keymap", None, "en-us")
|
||||
|
||||
check = self._make_checker(dev2)
|
||||
check("type", "sdl")
|
||||
@ -480,7 +482,7 @@ class XMLParseTest(unittest.TestCase):
|
||||
check("display", "1:2", "6:1")
|
||||
|
||||
check = self._make_checker(dev3)
|
||||
check("type", "rdp")
|
||||
check("type", "rdp", "vnc")
|
||||
|
||||
check = self._make_checker(dev4)
|
||||
check("type", "vnc")
|
||||
@ -488,6 +490,9 @@ class XMLParseTest(unittest.TestCase):
|
||||
check("socket", "/tmp/foobar", "/var/lib/libvirt/socket/foo")
|
||||
|
||||
check = self._make_checker(dev5)
|
||||
check("autoport", True, False)
|
||||
|
||||
check = self._make_checker(dev6)
|
||||
check("type", "spice")
|
||||
check("passwd", "foobar", "newpass")
|
||||
check("port", 100, 6000)
|
||||
@ -496,6 +501,9 @@ class XMLParseTest(unittest.TestCase):
|
||||
check("channel_inputs_mode", "insecure", "secure")
|
||||
check("channel_main_mode", "secure", "any")
|
||||
check("channel_record_mode", "any", "insecure")
|
||||
check("channel_display_mode", "any", "secure")
|
||||
check("channel_cursor_mode", "any", "any")
|
||||
check("channel_playback_mode", "any", "insecure")
|
||||
check("passwdValidTo", "2010-04-09T15:51:00", "2011-01-07T19:08:00")
|
||||
|
||||
self._alter_compare(guest.get_xml_config(), outfile)
|
||||
|
@ -17,7 +17,6 @@
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
# MA 02110-1301 USA.
|
||||
|
||||
import re
|
||||
import os
|
||||
|
||||
from virtinst.VirtualDevice import VirtualDevice
|
||||
@ -25,24 +24,47 @@ from virtinst.xmlbuilder import XMLProperty
|
||||
|
||||
|
||||
def _get_mode_prop(channel_type):
|
||||
# pylint: disable=W0212
|
||||
xpath = "./channel[@name='%s']/@mode" % channel_type
|
||||
def get_mode(s):
|
||||
return s._channels.get(channel_type, None)
|
||||
def set_mode(s, val):
|
||||
s._channels[channel_type] = val
|
||||
return XMLProperty(get_mode, set_mode, xpath=xpath)
|
||||
return XMLProperty(xpath=xpath)
|
||||
|
||||
|
||||
def _validate_port(name, val):
|
||||
if val is None:
|
||||
return val
|
||||
val = int(val)
|
||||
|
||||
if val < 5900 and val != -1:
|
||||
raise ValueError(_("%s must be above 5900, or "
|
||||
"-1 for auto allocation") % name)
|
||||
return val
|
||||
|
||||
|
||||
def _int_or_none(val):
|
||||
if val is None:
|
||||
return val
|
||||
return int(val)
|
||||
|
||||
|
||||
def _yes_no_none(val):
|
||||
if val is None:
|
||||
return None
|
||||
return val and "yes" or "no"
|
||||
|
||||
|
||||
def _yes_bool(val):
|
||||
if val is None:
|
||||
return None
|
||||
return bool(val == "yes")
|
||||
|
||||
|
||||
class VirtualGraphics(VirtualDevice):
|
||||
|
||||
_virtual_device_type = VirtualDevice.VIRTUAL_DEV_GRAPHICS
|
||||
|
||||
TYPE_SDL = "sdl"
|
||||
TYPE_VNC = "vnc"
|
||||
TYPE_RDP = "rdp"
|
||||
TYPE_SPICE = "spice"
|
||||
types = [TYPE_VNC, TYPE_SDL, TYPE_RDP, TYPE_SPICE]
|
||||
TYPES = [TYPE_VNC, TYPE_SDL, TYPE_RDP, TYPE_SPICE]
|
||||
|
||||
CHANNEL_TYPE_MAIN = "main"
|
||||
CHANNEL_TYPE_DISPLAY = "display"
|
||||
@ -50,14 +72,14 @@ class VirtualGraphics(VirtualDevice):
|
||||
CHANNEL_TYPE_CURSOR = "cursor"
|
||||
CHANNEL_TYPE_PLAYBACK = "playback"
|
||||
CHANNEL_TYPE_RECORD = "record"
|
||||
channel_types = [CHANNEL_TYPE_MAIN, CHANNEL_TYPE_DISPLAY,
|
||||
CHANNEL_TYPES = [CHANNEL_TYPE_MAIN, CHANNEL_TYPE_DISPLAY,
|
||||
CHANNEL_TYPE_INPUTS, CHANNEL_TYPE_CURSOR,
|
||||
CHANNEL_TYPE_PLAYBACK, CHANNEL_TYPE_RECORD]
|
||||
|
||||
CHANNEL_MODE_SECURE = "secure"
|
||||
CHANNEL_MODE_INSECURE = "insecure"
|
||||
CHANNEL_MODE_ANY = "any"
|
||||
channel_modes = [CHANNEL_MODE_SECURE, CHANNEL_MODE_INSECURE,
|
||||
CHANNEL_MODES = [CHANNEL_MODE_SECURE, CHANNEL_MODE_INSECURE,
|
||||
CHANNEL_MODE_ANY]
|
||||
|
||||
KEYMAP_LOCAL = "local"
|
||||
@ -90,42 +112,45 @@ class VirtualGraphics(VirtualDevice):
|
||||
|
||||
return str(gtype).capitalize()
|
||||
|
||||
def __init__(self, conn, type=TYPE_VNC, port=-1, listen=None, passwd=None,
|
||||
keymap=KEYMAP_DEFAULT, parsexml=None,
|
||||
parsexmlnode=None, tlsPort=-1, channels=None,
|
||||
def __init__(self, conn, type=None, port=None, listen=None, passwd=None,
|
||||
keymap=None, parsexml=None,
|
||||
parsexmlnode=None, tlsPort=None, channels=None,
|
||||
passwdValidTo=None):
|
||||
# pylint: disable=W0622
|
||||
# Redefining built-in 'type', but it matches the XML so keep it
|
||||
|
||||
VirtualDevice.__init__(self, conn, parsexml, parsexmlnode)
|
||||
|
||||
self._type = None
|
||||
self._port = None
|
||||
self._tlsPort = None
|
||||
self._listen = None
|
||||
self._passwd = None
|
||||
self._passwdValidTo = None
|
||||
self._keymap = None
|
||||
self._xauth = None
|
||||
self._display = None
|
||||
self._socket = None
|
||||
self._channels = {}
|
||||
self._local_keymap = -1
|
||||
|
||||
if self._is_parse():
|
||||
return
|
||||
|
||||
self.type = type
|
||||
self.port = port
|
||||
self.tlsPort = tlsPort
|
||||
self.keymap = keymap
|
||||
self.listen = listen
|
||||
self.passwd = passwd
|
||||
self.passwdValidTo = passwdValidTo
|
||||
if type:
|
||||
self.type = type
|
||||
if port:
|
||||
self.port = port
|
||||
if tlsPort:
|
||||
self.tlsPort = tlsPort
|
||||
if keymap:
|
||||
self.keymap = keymap
|
||||
if listen:
|
||||
self.listen = listen
|
||||
if passwd:
|
||||
self.passwd = passwd
|
||||
if passwdValidTo:
|
||||
self.passwdValidTo = passwdValidTo
|
||||
if channels:
|
||||
self.channels = channels
|
||||
|
||||
|
||||
_XML_PROP_ORDER = ["type", "port", "tlsPort", "autoport",
|
||||
"keymap", "listen",
|
||||
"passwd", "display", "xauth"]
|
||||
|
||||
def _default_keymap(self, force_local=False):
|
||||
if self.type != "vnc" and self.type != "spice":
|
||||
return None
|
||||
|
||||
if (not force_local and
|
||||
self.conn.check_conn_support(
|
||||
self.conn.SUPPORT_CONN_KEYMAP_AUTODETECT)):
|
||||
@ -136,124 +161,42 @@ class VirtualGraphics(VirtualDevice):
|
||||
self._local_keymap = hostkeymap.default_keymap()
|
||||
return self._local_keymap
|
||||
|
||||
def get_type(self):
|
||||
return self._type
|
||||
def set_type(self, val):
|
||||
if val not in self.types:
|
||||
raise ValueError(_("Unknown graphics type '%s'") % val)
|
||||
|
||||
self._type = val
|
||||
type = XMLProperty(get_type, set_type,
|
||||
xpath="./@type")
|
||||
|
||||
def _get_xauth(self):
|
||||
return self._xauth
|
||||
def _set_xauth(self, val):
|
||||
self._xauth = val
|
||||
xauth = XMLProperty(_get_xauth, _set_xauth,
|
||||
xpath="./@xauth")
|
||||
|
||||
def _get_display(self):
|
||||
return self._display
|
||||
def _set_display(self, val):
|
||||
self._display = val
|
||||
display = XMLProperty(_get_display, _set_display,
|
||||
xpath="./@display")
|
||||
|
||||
def get_keymap(self):
|
||||
if self._keymap == self.KEYMAP_DEFAULT:
|
||||
def _set_keymap_converter(self, val):
|
||||
if val == self.KEYMAP_DEFAULT:
|
||||
return self._default_keymap()
|
||||
if self._keymap == self.KEYMAP_LOCAL:
|
||||
if val == self.KEYMAP_LOCAL:
|
||||
return self._default_keymap(force_local=True)
|
||||
return self._keymap
|
||||
def set_keymap(self, val):
|
||||
# At this point, 'None' is a valid value
|
||||
if val is None:
|
||||
self._keymap = None
|
||||
return
|
||||
return val
|
||||
keymap = XMLProperty(xpath="./@keymap",
|
||||
default_cb=_default_keymap,
|
||||
set_converter=_set_keymap_converter)
|
||||
|
||||
if val in self._special_keymaps:
|
||||
self._keymap = val
|
||||
return
|
||||
|
||||
if type(val) is not str:
|
||||
raise ValueError(_("Keymap must be a string"))
|
||||
if val.lower() == self.KEYMAP_LOCAL:
|
||||
val = self._default_keymap(force_local=True)
|
||||
elif len(val) > 16:
|
||||
raise ValueError(_("Keymap must be less than 16 characters"))
|
||||
elif re.match("^[a-zA-Z0-9_-]*$", val) is None:
|
||||
raise ValueError(_("Keymap can only contain alphanumeric, "
|
||||
"'_', or '-' characters"))
|
||||
|
||||
self._keymap = val
|
||||
keymap = XMLProperty(get_keymap, set_keymap,
|
||||
xpath="./@keymap")
|
||||
|
||||
def get_port(self):
|
||||
return self._port
|
||||
def set_port(self, val):
|
||||
if val is None:
|
||||
val = -1
|
||||
|
||||
try:
|
||||
val = int(val)
|
||||
except:
|
||||
pass
|
||||
|
||||
if (type(val) is not int or
|
||||
(val != -1 and (val < 5900 or val > 65535))):
|
||||
raise ValueError(_("VNC port must be a number between "
|
||||
"5900 and 65535, or -1 for auto allocation"))
|
||||
self._port = val
|
||||
port = XMLProperty(get_port, set_port, is_int=True, xpath="./@port")
|
||||
|
||||
def get_listen(self):
|
||||
return self._listen
|
||||
def set_listen(self, val):
|
||||
self._listen = val
|
||||
listen = XMLProperty(get_listen, set_listen,
|
||||
xpath="./@listen")
|
||||
|
||||
def get_passwd(self):
|
||||
return self._passwd
|
||||
def set_passwd(self, val):
|
||||
self._passwd = val
|
||||
passwd = XMLProperty(get_passwd, set_passwd,
|
||||
xpath="./@passwd")
|
||||
|
||||
def get_passwdValidTo(self):
|
||||
return self._passwdValidTo
|
||||
def set_passwdValidTo(self, val):
|
||||
self._passwdValidTo = val
|
||||
passwdValidTo = XMLProperty(get_passwdValidTo, set_passwdValidTo,
|
||||
xpath="./@passwdValidTo")
|
||||
|
||||
def _get_socket(self):
|
||||
return self._socket
|
||||
def _set_socket(self, val):
|
||||
self._socket = val
|
||||
socket = XMLProperty(_get_socket, _set_socket,
|
||||
xpath="./@socket")
|
||||
|
||||
def get_tlsPort(self):
|
||||
return self._tlsPort
|
||||
def set_tlsPort(self, val):
|
||||
if val is None:
|
||||
val = -1
|
||||
|
||||
try:
|
||||
val = int(val)
|
||||
except:
|
||||
pass
|
||||
|
||||
if (type(val) is not int or
|
||||
(val != -1 and (val < 5900 or val > 65535))):
|
||||
raise ValueError(_("TLS port must be a number between "
|
||||
"5900 and 65535, or -1 for auto allocation"))
|
||||
self._tlsPort = val
|
||||
tlsPort = XMLProperty(get_tlsPort, set_tlsPort, is_int=True,
|
||||
xpath="./@tlsPort")
|
||||
def _get_default_port(self):
|
||||
if self.type == "vnc" or self.type == "spice":
|
||||
return -1
|
||||
return None
|
||||
def _get_default_tlsport(self):
|
||||
if self.type == "spice":
|
||||
return -1
|
||||
return None
|
||||
def _get_default_autoport(self):
|
||||
# By default, don't do this for VNC to maintain back compat with
|
||||
# old libvirt that didn't support 'autoport'
|
||||
if self.type == "spice":
|
||||
return (self.port == -1 or self.tlsPort == -1) and "yes" or "no"
|
||||
return None
|
||||
port = XMLProperty(xpath="./@port",
|
||||
get_converter=lambda s, v: _int_or_none(v),
|
||||
set_converter=lambda s, v: _validate_port("Port", v),
|
||||
default_cb=_get_default_port)
|
||||
tlsPort = XMLProperty(xpath="./@tlsPort",
|
||||
get_converter=lambda s, v: _int_or_none(v),
|
||||
set_converter=lambda s, v: _validate_port("TLS port", v),
|
||||
default_cb=_get_default_tlsport)
|
||||
autoport = XMLProperty(xpath="./@autoport",
|
||||
get_converter=lambda s, v: _yes_bool(v),
|
||||
set_converter=lambda s, v: _yes_no_none(v),
|
||||
default_cb=_get_default_autoport)
|
||||
|
||||
channel_main_mode = _get_mode_prop(CHANNEL_TYPE_MAIN)
|
||||
channel_display_mode = _get_mode_prop(CHANNEL_TYPE_DISPLAY)
|
||||
@ -262,82 +205,25 @@ class VirtualGraphics(VirtualDevice):
|
||||
channel_playback_mode = _get_mode_prop(CHANNEL_TYPE_PLAYBACK)
|
||||
channel_record_mode = _get_mode_prop(CHANNEL_TYPE_RECORD)
|
||||
|
||||
def _build_xml(self, port=None, listen=None, keymap=None, passwd=None,
|
||||
display=None, xauth=None, tlsPort=None, canautoport=False,
|
||||
passwdValidTo=None, socket=None):
|
||||
|
||||
doautoport = (canautoport and
|
||||
(port in [None, -1] and
|
||||
tlsPort in [None, -1]))
|
||||
portxml = (port is not None and (" port='%d'" % port) or "")
|
||||
tlsportxml = (tlsPort is not None and (" tlsPort='%d'" % tlsPort) or "")
|
||||
autoportxml = (doautoport and " autoport='yes'" or "")
|
||||
|
||||
keymapxml = (keymap and (" keymap='%s'" % keymap) or "")
|
||||
listenxml = (listen and (" listen='%s'" % listen) or "")
|
||||
passwdxml = (passwd and (" passwd='%s'" % passwd) or "")
|
||||
passwdValidToxml = (passwdValidTo and
|
||||
(" passwdValidTo='%s'" % passwdValidTo) or "")
|
||||
|
||||
xauthxml = (xauth and (" xauth='%s'" % xauth) or "")
|
||||
displayxml = (display and (" display='%s'" % display) or "")
|
||||
|
||||
socketxml = (socket and (" socket='%s'" % socket) or "")
|
||||
|
||||
xml = (" " +
|
||||
"<graphics type='%s'" % self.type +
|
||||
portxml +
|
||||
tlsportxml +
|
||||
autoportxml +
|
||||
keymapxml +
|
||||
listenxml +
|
||||
passwdxml +
|
||||
passwdValidToxml +
|
||||
socketxml +
|
||||
displayxml +
|
||||
xauthxml +
|
||||
"/>")
|
||||
return xml
|
||||
|
||||
def _sdl_config(self):
|
||||
if "DISPLAY" not in os.environ and not self.display:
|
||||
def _get_default_display(self):
|
||||
if self.type != "sdl":
|
||||
return None
|
||||
if "DISPLAY" not in os.environ:
|
||||
raise RuntimeError("No DISPLAY environment variable set.")
|
||||
return os.environ["DISPLAY"]
|
||||
def _get_default_xauth(self):
|
||||
if self.type != "sdl":
|
||||
return None
|
||||
return os.path.expanduser("~/.Xauthority")
|
||||
xauth = XMLProperty(xpath="./@xauth",
|
||||
default_cb=_get_default_xauth)
|
||||
display = XMLProperty(xpath="./@display",
|
||||
default_cb=_get_default_display)
|
||||
|
||||
disp = self.display or os.environ["DISPLAY"]
|
||||
xauth = self.xauth or os.path.expanduser("~/.Xauthority")
|
||||
|
||||
return self._build_xml(display=disp, xauth=xauth)
|
||||
|
||||
def _spice_config(self):
|
||||
port = self.port
|
||||
if port is None:
|
||||
port = -1
|
||||
tlsport = self.tlsPort
|
||||
if tlsport is None:
|
||||
tlsport = -1
|
||||
return self._build_xml(port=port, keymap=self.keymap,
|
||||
passwd=self.passwd, listen=self.listen,
|
||||
tlsPort=tlsport, canautoport=True,
|
||||
passwdValidTo=self.passwdValidTo)
|
||||
|
||||
def _vnc_config(self):
|
||||
port = self.port
|
||||
if port is None:
|
||||
port = -1
|
||||
return self._build_xml(port=port, keymap=self.keymap,
|
||||
passwd=self.passwd, listen=self.listen,
|
||||
# VNC supports autoport, but use legacy
|
||||
# syntax to not break XML tests
|
||||
canautoport=False,
|
||||
passwdValidTo=self.passwdValidTo,
|
||||
socket=self.socket)
|
||||
|
||||
def _get_xml_config(self):
|
||||
if self._type == self.TYPE_SDL:
|
||||
return self._sdl_config()
|
||||
if self._type == self.TYPE_SPICE:
|
||||
return self._spice_config()
|
||||
if self._type == self.TYPE_VNC:
|
||||
return self._vnc_config()
|
||||
else:
|
||||
raise ValueError(_("Unknown graphics type"))
|
||||
type = XMLProperty(xpath="./@type", default_cb=lambda s: "vnc")
|
||||
listen = XMLProperty(xpath="./@listen")
|
||||
passwd = XMLProperty(xpath="./@passwd")
|
||||
passwdValidTo = XMLProperty(xpath="./@passwdValidTo")
|
||||
socket = XMLProperty(xpath="./@socket")
|
||||
|
Loading…
Reference in New Issue
Block a user