VirtualCharDevice: Convert to new style XML props, rework API
This commit is contained in:
parent
9f37f58804
commit
e802eae07b
|
@ -25,7 +25,8 @@ from virtinst import VirtualDisk
|
|||
from virtinst import VirtualAudio
|
||||
from virtinst import VirtualNetworkInterface
|
||||
from virtinst import VirtualHostDevice
|
||||
from virtinst import VirtualCharDevice
|
||||
from virtinst import (VirtualChannelDevice, VirtualConsoleDevice,
|
||||
VirtualParallelDevice, VirtualSerialDevice)
|
||||
from virtinst import VirtualVideoDevice
|
||||
from virtinst import VirtualController
|
||||
from virtinst import VirtualWatchdog
|
||||
|
@ -313,9 +314,8 @@ class TestXMLConfig(unittest.TestCase):
|
|||
g.add_device(utils.get_filedisk())
|
||||
|
||||
inp = VirtualInputDevice(g.conn)
|
||||
cons = VirtualCharDevice.get_dev_instance(g.conn,
|
||||
VirtualCharDevice.DEV_CONSOLE,
|
||||
VirtualCharDevice.CHAR_PTY)
|
||||
cons = VirtualConsoleDevice(g.conn)
|
||||
cons.type = "pty"
|
||||
g.add_device(inp)
|
||||
g.add_device(cons)
|
||||
|
||||
|
@ -679,46 +679,38 @@ class TestXMLConfig(unittest.TestCase):
|
|||
i = utils.make_pxe_installer()
|
||||
g = utils.get_basic_fullyvirt_guest(installer=i)
|
||||
|
||||
dev1 = VirtualCharDevice.get_dev_instance(g.conn,
|
||||
VirtualCharDevice.DEV_SERIAL,
|
||||
VirtualCharDevice.CHAR_NULL)
|
||||
dev2 = VirtualCharDevice.get_dev_instance(g.conn,
|
||||
VirtualCharDevice.DEV_PARALLEL,
|
||||
VirtualCharDevice.CHAR_UNIX)
|
||||
dev1 = VirtualSerialDevice(g.conn)
|
||||
dev1.type = "null"
|
||||
dev2 = VirtualParallelDevice(g.conn)
|
||||
dev2.type = "unix"
|
||||
dev2.source_path = "/tmp/foobar"
|
||||
dev3 = VirtualCharDevice.get_dev_instance(g.conn,
|
||||
VirtualCharDevice.DEV_SERIAL,
|
||||
VirtualCharDevice.CHAR_TCP)
|
||||
dev3 = VirtualSerialDevice(g.conn)
|
||||
dev3.type = "tcp"
|
||||
dev3.protocol = "telnet"
|
||||
dev3.source_host = "my.source.host"
|
||||
dev3.source_port = "1234"
|
||||
dev4 = VirtualCharDevice.get_dev_instance(g.conn,
|
||||
VirtualCharDevice.DEV_PARALLEL,
|
||||
VirtualCharDevice.CHAR_UDP)
|
||||
dev4 = VirtualParallelDevice(g.conn)
|
||||
dev4.type = "udp"
|
||||
dev4.bind_host = "my.bind.host"
|
||||
dev4.bind_port = "1111"
|
||||
dev4.source_host = "my.source.host"
|
||||
dev4.source_port = "2222"
|
||||
|
||||
dev5 = VirtualCharDevice.get_dev_instance(g.conn,
|
||||
VirtualCharDevice.DEV_CHANNEL,
|
||||
VirtualCharDevice.CHAR_PTY)
|
||||
dev5.target_type = dev5.CHAR_CHANNEL_TARGET_VIRTIO
|
||||
dev5 = VirtualChannelDevice(g.conn)
|
||||
dev5.type = "pty"
|
||||
dev5.target_type = dev5.CHANNEL_TARGET_VIRTIO
|
||||
dev5.target_name = "foo.bar.frob"
|
||||
|
||||
dev6 = VirtualCharDevice.get_dev_instance(g.conn,
|
||||
VirtualCharDevice.DEV_CONSOLE,
|
||||
VirtualCharDevice.CHAR_PTY)
|
||||
dev6 = VirtualConsoleDevice(g.conn)
|
||||
dev6.type = "pty"
|
||||
|
||||
dev7 = VirtualCharDevice.get_dev_instance(g.conn,
|
||||
VirtualCharDevice.DEV_CONSOLE,
|
||||
VirtualCharDevice.CHAR_PTY)
|
||||
dev7.target_type = dev5.CHAR_CONSOLE_TARGET_VIRTIO
|
||||
dev7 = VirtualConsoleDevice(g.conn)
|
||||
dev7.type = "pty"
|
||||
dev7.target_type = dev7.CONSOLE_TARGET_VIRTIO
|
||||
|
||||
dev8 = VirtualCharDevice.get_dev_instance(g.conn,
|
||||
VirtualCharDevice.DEV_CHANNEL,
|
||||
VirtualCharDevice.CHAR_PTY)
|
||||
dev8.target_type = dev5.CHAR_CHANNEL_TARGET_GUESTFWD
|
||||
dev8 = VirtualChannelDevice(g.conn)
|
||||
dev8.type = "pty"
|
||||
dev8.target_type = dev8.CHANNEL_TARGET_GUESTFWD
|
||||
dev8.target_address = "1.2.3.4"
|
||||
dev8.target_port = "4567"
|
||||
|
||||
|
@ -811,16 +803,13 @@ class TestXMLConfig(unittest.TestCase):
|
|||
g.add_device(net3)
|
||||
|
||||
# Character devices
|
||||
cdev1 = VirtualCharDevice.get_dev_instance(g.conn,
|
||||
VirtualCharDevice.DEV_SERIAL,
|
||||
VirtualCharDevice.CHAR_NULL)
|
||||
cdev2 = VirtualCharDevice.get_dev_instance(g.conn,
|
||||
VirtualCharDevice.DEV_PARALLEL,
|
||||
VirtualCharDevice.CHAR_UNIX)
|
||||
cdev1 = VirtualSerialDevice(g.conn)
|
||||
cdev1.type = "null"
|
||||
cdev2 = VirtualParallelDevice(g.conn)
|
||||
cdev2.type = "unix"
|
||||
cdev2.source_path = "/tmp/foobar"
|
||||
cdev3 = VirtualCharDevice.get_dev_instance(g.conn,
|
||||
VirtualCharDevice.DEV_CHANNEL,
|
||||
VirtualCharDevice.CHAR_SPICEVMC)
|
||||
cdev3 = VirtualChannelDevice(g.conn)
|
||||
cdev3.type = "spicevmc"
|
||||
g.add_device(cdev1)
|
||||
g.add_device(cdev2)
|
||||
g.add_device(cdev3)
|
||||
|
|
|
@ -20,7 +20,10 @@
|
|||
<emulator>/usr/lib/xen/bin/qemu-dm</emulator>
|
||||
<input type="mouse" bus="ps2"/>
|
||||
<graphics type="sdl" display=":3.4" xauth="/tmp/.Xauthority"/>
|
||||
<serial type="null"/>
|
||||
<serial type="udp">
|
||||
<source mode="bind" host="example.com" service="66"/>
|
||||
<source mode="connect" host="example.com.uk" service="77"/>
|
||||
</serial>
|
||||
<serial type="tcp">
|
||||
<source mode="connect" host="my.source.host" service="1234"/>
|
||||
<protocol type="raw"/>
|
||||
|
|
|
@ -312,46 +312,50 @@ class XMLParseTest(unittest.TestCase):
|
|||
channel2 = guest.get_devices("channel")[1]
|
||||
|
||||
check = self._make_checker(serial1)
|
||||
check("char_type", "null")
|
||||
check("type", "null", "udp")
|
||||
check("bind_host", None, "example.com")
|
||||
check("bind_port", None, 66)
|
||||
check("source_host", None, "example.com.uk")
|
||||
check("source_port", None, 77)
|
||||
|
||||
check = self._make_checker(serial2)
|
||||
check("char_type", "tcp")
|
||||
check("type", "tcp")
|
||||
check("protocol", "telnet", "raw")
|
||||
check("source_mode", "bind", "connect")
|
||||
|
||||
check = self._make_checker(parallel1)
|
||||
check("source_mode", "bind")
|
||||
check("source_path", "/tmp/foobar", None)
|
||||
check("char_type", "unix", "pty")
|
||||
check("type", "unix", "pty")
|
||||
|
||||
check = self._make_checker(parallel2)
|
||||
check("char_type", "udp")
|
||||
check("bind_port", "1111", "1357")
|
||||
check("type", "udp")
|
||||
check("bind_port", 1111, 1357)
|
||||
check("bind_host", "my.bind.host", "my.foo.host")
|
||||
check("source_mode", "connect")
|
||||
check("source_port", "2222", "7777")
|
||||
check("source_port", 2222, 7777)
|
||||
check("source_host", "my.source.host", "source.foo.host")
|
||||
|
||||
check = self._make_checker(console1)
|
||||
check("char_type", "pty")
|
||||
check("type", "pty")
|
||||
check("target_type", None)
|
||||
|
||||
check = self._make_checker(console2)
|
||||
check("char_type", "file")
|
||||
check("type", "file")
|
||||
check("source_path", "/tmp/foo.img", None)
|
||||
check("source_path", None, "/root/foo")
|
||||
check("target_type", "virtio")
|
||||
|
||||
check = self._make_checker(channel1)
|
||||
check("char_type", "pty")
|
||||
check("target_type", "virtio")
|
||||
check("type", "pty")
|
||||
check("target_type", "virtio", "bar", "virtio")
|
||||
check("target_name", "foo.bar.frob", "test.changed")
|
||||
|
||||
check = self._make_checker(channel2)
|
||||
check("char_type", "unix")
|
||||
check("type", "unix", "foo", "unix")
|
||||
check("target_type", "guestfwd")
|
||||
check("target_address", "1.2.3.4", "5.6.7.8")
|
||||
check("target_port", "4567", "1199")
|
||||
check("target_port", 4567, 1199)
|
||||
|
||||
self._alter_compare(guest.get_xml_config(), outfile)
|
||||
|
||||
|
|
14
virt-install
14
virt-install
|
@ -33,11 +33,9 @@ import urlgrabber.progress as progress
|
|||
import virtinst
|
||||
import virtinst.cli as cli
|
||||
import virtinst.util as util
|
||||
from virtinst import VirtualCharDevice
|
||||
from virtinst.cli import fail, print_stdout, print_stderr
|
||||
|
||||
|
||||
|
||||
##############################
|
||||
# Validation utility helpers #
|
||||
##############################
|
||||
|
@ -529,14 +527,10 @@ def build_guest_instance(conn, options):
|
|||
get_watchdog(options.watchdog, guest)
|
||||
get_filesystems(options.filesystems, guest)
|
||||
cli.get_sound(options.sound, options.soundhw, guest)
|
||||
get_chardevs(VirtualCharDevice.VIRTUAL_DEV_SERIAL, options.serials,
|
||||
guest, cli.parse_serial)
|
||||
get_chardevs(VirtualCharDevice.VIRTUAL_DEV_PARALLEL, options.parallels,
|
||||
guest, cli.parse_parallel)
|
||||
get_chardevs(VirtualCharDevice.VIRTUAL_DEV_CHANNEL, options.channels,
|
||||
guest, cli.parse_channel)
|
||||
get_chardevs(VirtualCharDevice.VIRTUAL_DEV_CONSOLE, options.consoles,
|
||||
guest, cli.parse_console)
|
||||
get_chardevs("serial", options.serials, guest, cli.parse_serial)
|
||||
get_chardevs("parallel", options.parallels, guest, cli.parse_parallel)
|
||||
get_chardevs("channel", options.channels, guest, cli.parse_channel)
|
||||
get_chardevs("console", options.consoles, guest, cli.parse_console)
|
||||
cli.get_hostdevs(options.hostdevs, guest)
|
||||
cli.get_smartcard(guest, options.smartcard)
|
||||
cli.get_tpm(guest, options.tpm)
|
||||
|
|
|
@ -27,7 +27,8 @@ from gi.repository import Gdk
|
|||
# pylint: enable=E0611
|
||||
|
||||
import virtinst
|
||||
from virtinst import (VirtualCharDevice,
|
||||
from virtinst import (VirtualChannelDevice, VirtualParallelDevice,
|
||||
VirtualSerialDevice,
|
||||
VirtualVideoDevice, VirtualWatchdog,
|
||||
VirtualFilesystem, VirtualSmartCardDevice,
|
||||
VirtualRedirDevice, VirtualTPMDevice)
|
||||
|
@ -132,7 +133,7 @@ class vmmAddHardware(vmmGObjectUI):
|
|||
self.widget("char-info").set_markup(doc)
|
||||
|
||||
def update_doc_char_type(self, *ignore):
|
||||
return self._update_doc("char_type")
|
||||
return self._update_doc("type")
|
||||
def update_doc_char_source_path(self, *ignore):
|
||||
return self._update_doc("source_path")
|
||||
def update_doc_char_source_mode(self, *ignore):
|
||||
|
@ -147,18 +148,17 @@ class vmmAddHardware(vmmGObjectUI):
|
|||
return self._update_doc("target_name")
|
||||
|
||||
def _build_doc_str(self, param, docstr=None):
|
||||
doc = ""
|
||||
doctmpl = "<i>%s</i>"
|
||||
|
||||
if docstr:
|
||||
doc = doctmpl % (docstr)
|
||||
elif self._dev:
|
||||
devclass = self._dev.__class__
|
||||
paramdoc = getattr(devclass, param).__doc__
|
||||
if paramdoc:
|
||||
doc = doctmpl % paramdoc
|
||||
return doctmpl % (docstr)
|
||||
elif not self._dev:
|
||||
return ""
|
||||
|
||||
return doc
|
||||
propdoc = getattr(self._dev.all_xml_props()[param], "__doc__")
|
||||
if propdoc:
|
||||
return doctmpl % propdoc
|
||||
return ""
|
||||
|
||||
def show(self, parent):
|
||||
logging.debug("Showing addhw")
|
||||
|
@ -303,8 +303,8 @@ class vmmAddHardware(vmmGObjectUI):
|
|||
char_mode.pack_start(text, True)
|
||||
char_mode.add_attribute(text, 'text', 1)
|
||||
char_mode_model.set_sort_column_id(0, Gtk.SortType.ASCENDING)
|
||||
for t in VirtualCharDevice.char_modes:
|
||||
desc = VirtualCharDevice.get_char_mode_desc(t)
|
||||
for t in VirtualSerialDevice.MODES:
|
||||
desc = VirtualSerialDevice.pretty_mode(t)
|
||||
char_mode_model.append([t, desc + " (%s)" % t])
|
||||
|
||||
self.widget("char-info-box").modify_bg(Gtk.StateType.NORMAL,
|
||||
|
@ -833,7 +833,8 @@ class vmmAddHardware(vmmGObjectUI):
|
|||
|
||||
# Char device type
|
||||
char_devtype = self.widget("char-device-type")
|
||||
dev_type = self.get_char_type()
|
||||
char_class = self.get_char_type()
|
||||
|
||||
# Type name, desc
|
||||
char_devtype_model = Gtk.ListStore(str, str)
|
||||
char_devtype.clear()
|
||||
|
@ -842,12 +843,12 @@ class vmmAddHardware(vmmGObjectUI):
|
|||
char_devtype.pack_start(text, True)
|
||||
char_devtype.add_attribute(text, 'text', 1)
|
||||
|
||||
for t in VirtualCharDevice.char_types_for_dev_type[dev_type]:
|
||||
for t in char_class.TYPES:
|
||||
if (t in rhel6_blacklist and
|
||||
not self.vm.rhel6_defaults()):
|
||||
continue
|
||||
|
||||
desc = VirtualCharDevice.get_char_type_desc(t)
|
||||
desc = char_class.pretty_type(t)
|
||||
row = [t, desc + " (%s)" % t]
|
||||
char_devtype_model.append(row)
|
||||
char_devtype.set_active(0)
|
||||
|
@ -988,10 +989,10 @@ class vmmAddHardware(vmmGObjectUI):
|
|||
label = row[5]
|
||||
|
||||
if label == "parallel":
|
||||
return VirtualCharDevice.VIRTUAL_DEV_PARALLEL
|
||||
return VirtualParallelDevice
|
||||
elif label == "channel":
|
||||
return VirtualCharDevice.VIRTUAL_DEV_CHANNEL
|
||||
return VirtualCharDevice.VIRTUAL_DEV_SERIAL
|
||||
return VirtualChannelDevice
|
||||
return VirtualSerialDevice
|
||||
|
||||
def dev_to_title(self, page):
|
||||
if page == PAGE_ERROR:
|
||||
|
@ -1020,7 +1021,8 @@ class vmmAddHardware(vmmGObjectUI):
|
|||
return _("TPM")
|
||||
|
||||
if page == PAGE_CHAR:
|
||||
return self.get_char_type().capitalize() + " Device"
|
||||
char_class = self.get_char_type()
|
||||
return char_class.virtual_device_type.capitalize() + " Device"
|
||||
if page == PAGE_HOSTDEV:
|
||||
return self.get_config_host_device_type_info()[0]
|
||||
|
||||
|
@ -1056,16 +1058,17 @@ class vmmAddHardware(vmmGObjectUI):
|
|||
self.widget("tpm-param-box").set_property("visible", show_something)
|
||||
|
||||
def change_char_device_type(self, src):
|
||||
self._update_doc("char_type")
|
||||
self._update_doc("type")
|
||||
idx = src.get_active()
|
||||
if idx < 0:
|
||||
return
|
||||
|
||||
chartype = self.get_char_type()
|
||||
char_class = self.get_char_type()
|
||||
devtype = src.get_model()[src.get_active()][0]
|
||||
conn = self.conn.get_backend()
|
||||
|
||||
self._dev = VirtualCharDevice.get_dev_instance(conn, chartype, devtype)
|
||||
self._dev = char_class(conn)
|
||||
self._dev.type = devtype
|
||||
|
||||
show_something = False
|
||||
for param_name, widget_name in char_widget_mappings.items():
|
||||
|
@ -1472,13 +1475,14 @@ class vmmAddHardware(vmmGObjectUI):
|
|||
return self.err.val_err(_("Host device parameter error"), e)
|
||||
|
||||
def validate_page_char(self):
|
||||
chartype = self.get_char_type()
|
||||
charclass = self.get_char_type()
|
||||
modebox = self.widget("char-mode")
|
||||
devbox = self.widget("char-device-type")
|
||||
devtype = devbox.get_model()[devbox.get_active()][0]
|
||||
conn = self.conn.get_backend()
|
||||
|
||||
devclass = VirtualCharDevice.get_dev_instance(conn, chartype, devtype)
|
||||
devclass = charclass(conn)
|
||||
devclass.type = devtype
|
||||
|
||||
source_path = self.widget("char-path").get_text()
|
||||
source_mode = modebox.get_model()[modebox.get_active()][0]
|
||||
|
@ -1489,9 +1493,9 @@ class vmmAddHardware(vmmGObjectUI):
|
|||
target_name = self.widget("char-target-name").get_text()
|
||||
|
||||
if self.widget("char-use-telnet").get_active():
|
||||
protocol = VirtualCharDevice.CHAR_PROTOCOL_TELNET
|
||||
protocol = VirtualSerialDevice.PROTOCOL_TELNET
|
||||
else:
|
||||
protocol = VirtualCharDevice.CHAR_PROTOCOL_RAW
|
||||
protocol = VirtualSerialDevice.PROTOCOL_RAW
|
||||
|
||||
value_mappings = {
|
||||
"source_path" : source_path,
|
||||
|
@ -1514,8 +1518,9 @@ class vmmAddHardware(vmmGObjectUI):
|
|||
# Dump XML for sanity checking
|
||||
self._dev.get_xml_config()
|
||||
except Exception, e:
|
||||
return self.err.val_err(_("%s device parameter error") %
|
||||
chartype.capitalize(), e)
|
||||
return self.err.val_err(
|
||||
_("%s device parameter error") %
|
||||
charclass.virtual_device_type.capitalize(), e)
|
||||
|
||||
def validate_page_video(self):
|
||||
conn = self.conn.get_backend()
|
||||
|
|
|
@ -2417,8 +2417,8 @@ class vmmDetails(vmmGObjectUI):
|
|||
has_multi_spice = (len([d for d in self.vm.get_graphics_devices() if
|
||||
d.type == d.TYPE_SPICE]) > 1)
|
||||
has_spicevmc = bool([d for d in self.vm.get_char_devices() if
|
||||
(d.dev_type == d.DEV_CHANNEL and
|
||||
d.char_type == d.CHAR_SPICEVMC)])
|
||||
(d.virtual_device_type == "channel" and
|
||||
d.type == "spicevmc")])
|
||||
fromspice = (gdev.type == "spice")
|
||||
tospice = (newgtype == "spice")
|
||||
|
||||
|
@ -3234,8 +3234,8 @@ class vmmDetails(vmmGObjectUI):
|
|||
if not chardev:
|
||||
return
|
||||
|
||||
show_target_type = not (chardev.dev_type in
|
||||
[chardev.DEV_SERIAL, chardev.DEV_PARALLEL])
|
||||
show_target_type = not (chardev.virtual_device_type in
|
||||
["serial", "parallel"])
|
||||
|
||||
def show_ui(param, val=None):
|
||||
widgetname = "char-" + param.replace("_", "-")
|
||||
|
@ -3268,7 +3268,7 @@ class vmmDetails(vmmGObjectUI):
|
|||
|
||||
char_type = chardev.virtual_device_type.capitalize()
|
||||
target_port = chardev.target_port
|
||||
dev_type = chardev.char_type or "pty"
|
||||
dev_type = chardev.type or "pty"
|
||||
primary = hasattr(chardev, "virtmanager_console_dup")
|
||||
|
||||
typelabel = ""
|
||||
|
|
|
@ -28,7 +28,6 @@ import threading
|
|||
|
||||
import libvirt
|
||||
import virtinst
|
||||
from virtinst.VirtualCharDevice import VirtualCharSpicevmcDevice
|
||||
|
||||
from virtManager import util
|
||||
from virtManager.libvirtobject import vmmLibvirtObject
|
||||
|
@ -45,12 +44,12 @@ def compare_device(origdev, newdev, idx):
|
|||
"hostdev" : ["type", "managed", "vmmindex",
|
||||
"product", "vendor",
|
||||
"function", "domain", "slot"],
|
||||
"serial" : ["char_type", "target_port"],
|
||||
"parallel" : ["char_type", "target_port"],
|
||||
"console" : ["char_type", "target_type", "target_port"],
|
||||
"serial" : ["type", "target_port"],
|
||||
"parallel" : ["type", "target_port"],
|
||||
"console" : ["type", "target_type", "target_port"],
|
||||
"graphics" : ["type", "vmmindex"],
|
||||
"controller" : ["type", "index"],
|
||||
"channel" : ["char_type", "target_name"],
|
||||
"channel" : ["type", "target_name"],
|
||||
"filesystem" : ["target" , "vmmindex"],
|
||||
"smartcard" : ["mode" , "vmmindex"],
|
||||
"redirdev" : ["bus" , "type", "vmmindex"],
|
||||
|
@ -740,12 +739,13 @@ class vmmDomain(vmmLibvirtObject):
|
|||
is_spice = (newval == virtinst.VirtualGraphics.TYPE_SPICE)
|
||||
|
||||
if is_spice:
|
||||
guest.add_device(VirtualCharSpicevmcDevice(guest.conn))
|
||||
dev = virtinst.VirtualChannelDevice(guest.conn)
|
||||
dev.type = dev.TYPE_SPICEVMC
|
||||
guest.add_device(dev)
|
||||
else:
|
||||
channels = guest.get_devices("channel")
|
||||
channels = [x for x in channels if
|
||||
(x.char_type ==
|
||||
virtinst.VirtualCharDevice.CHAR_SPICEVMC)]
|
||||
channels = [x for x in guest.get_devices("channel")
|
||||
if x.type == "spicevmc"]
|
||||
for dev in channels:
|
||||
guest.remove_device(dev)
|
||||
|
||||
|
@ -1109,7 +1109,7 @@ class vmmDomain(vmmLibvirtObject):
|
|||
con = consoles[0]
|
||||
ser = serials[0]
|
||||
|
||||
if (con.char_type == ser.char_type and
|
||||
if (con.type == ser.type and
|
||||
con.target_type is None or con.target_type == "serial"):
|
||||
ser.virtmanager_console_dup = con
|
||||
devs.remove(con)
|
||||
|
|
|
@ -264,7 +264,7 @@ class vmmSerialConsole(vmmGObject):
|
|||
"""
|
||||
usable_types = ["pty"]
|
||||
|
||||
ctype = dev.char_type
|
||||
ctype = dev.type
|
||||
path = dev.source_path
|
||||
is_remote = vm.conn.is_remote()
|
||||
support_tunnel = vmmSerialConsole.support_remote_console(vm)
|
||||
|
|
|
@ -35,7 +35,6 @@ from virtinst.xmlbuilder import XMLBuilder, XMLProperty
|
|||
from virtinst.VirtualDevice import VirtualDevice
|
||||
from virtinst.VirtualDisk import VirtualDisk
|
||||
from virtinst.VirtualInputDevice import VirtualInputDevice
|
||||
from virtinst.VirtualCharDevice import VirtualCharDevice
|
||||
from virtinst.VirtualController import VirtualController
|
||||
from virtinst.Clock import Clock
|
||||
from virtinst.Seclabel import Seclabel
|
||||
|
@ -626,10 +625,10 @@ class Guest(XMLBuilder):
|
|||
"sound" : virtinst.VirtualAudio,
|
||||
"hostdev" : virtinst.VirtualHostDevice,
|
||||
"input" : virtinst.VirtualInputDevice,
|
||||
"serial" : virtinst.VirtualCharDevice,
|
||||
"parallel" : virtinst.VirtualCharDevice,
|
||||
"console" : virtinst.VirtualCharDevice,
|
||||
"channel" : virtinst.VirtualCharDevice,
|
||||
"serial" : virtinst.VirtualSerialDevice,
|
||||
"parallel" : virtinst.VirtualParallelDevice,
|
||||
"console" : virtinst.VirtualConsoleDevice,
|
||||
"channel" : virtinst.VirtualChannelDevice,
|
||||
"graphics" : virtinst.VirtualGraphics,
|
||||
"video" : virtinst.VirtualVideoDevice,
|
||||
"watchdog" : virtinst.VirtualWatchdog,
|
||||
|
@ -653,11 +652,7 @@ class Guest(XMLBuilder):
|
|||
devnode.virtinst_root_doc = self._xml_root_doc
|
||||
objclass = device_mappings.get(devnode.name)
|
||||
|
||||
if objclass == virtinst.VirtualCharDevice:
|
||||
dev = objclass(self.conn, devnode.name,
|
||||
parsexmlnode=devnode)
|
||||
else:
|
||||
dev = objclass(self.conn, parsexmlnode=devnode)
|
||||
dev = objclass(self.conn, parsexmlnode=devnode)
|
||||
self._add_device(dev)
|
||||
|
||||
self._xml_node.virtinst_root_doc = self._xml_root_doc
|
||||
|
@ -681,9 +676,8 @@ class Guest(XMLBuilder):
|
|||
return dev
|
||||
|
||||
def _get_default_console_device(self):
|
||||
dev = VirtualCharDevice.get_dev_instance(self.conn,
|
||||
VirtualCharDevice.DEV_CONSOLE,
|
||||
VirtualCharDevice.CHAR_PTY)
|
||||
dev = virtinst.VirtualConsoleDevice(self.conn)
|
||||
dev.type = dev.TYPE_PTY
|
||||
return dev
|
||||
|
||||
def _get_device_xml(self, devs, install=True):
|
||||
|
@ -1383,16 +1377,15 @@ class Guest(XMLBuilder):
|
|||
# Spice agent channel (only if we use spice)
|
||||
def has_spice_agent():
|
||||
for chn in devlist_func(channeltype):
|
||||
if chn.char_type == chn.CHAR_SPICEVMC:
|
||||
if chn.type == chn.TYPE_SPICEVMC:
|
||||
return True
|
||||
|
||||
if (has_spice() and
|
||||
not has_spice_agent() and
|
||||
self.conn.check_conn_support(
|
||||
self.conn.SUPPORT_CONN_HV_CHAR_SPICEVMC)):
|
||||
agentdev = VirtualCharDevice.get_dev_instance(self.conn,
|
||||
VirtualCharDevice.DEV_CHANNEL,
|
||||
VirtualCharDevice.CHAR_SPICEVMC)
|
||||
agentdev = virtinst.VirtualChannelDevice(self.conn)
|
||||
agentdev.type = agentdev.TYPE_SPICEVMC
|
||||
self.add_device(agentdev)
|
||||
|
||||
# Generate UUID
|
||||
|
|
|
@ -22,7 +22,7 @@ from virtinst.xmlbuilder import XMLProperty
|
|||
|
||||
|
||||
class VirtualAudio(VirtualDevice):
|
||||
_virtual_device_type = VirtualDevice.VIRTUAL_DEV_AUDIO
|
||||
virtual_device_type = VirtualDevice.VIRTUAL_DEV_AUDIO
|
||||
|
||||
MODEL_DEFAULT = "default"
|
||||
MODELS = ["es1370", "sb16", "pcspk", "ac97", "ich6", MODEL_DEFAULT]
|
||||
|
|
|
@ -18,617 +18,262 @@
|
|||
# MA 02110-1301 USA.
|
||||
|
||||
from virtinst.VirtualDevice import VirtualDevice
|
||||
from virtinst.util import xml_escape
|
||||
|
||||
from virtinst.xmlbuilder import XMLProperty
|
||||
|
||||
|
||||
class VirtualCharDevice(VirtualDevice):
|
||||
class _VirtualCharDevice(VirtualDevice):
|
||||
"""
|
||||
Base class for all character devices. Shouldn't be instantiated
|
||||
directly.
|
||||
"""
|
||||
|
||||
DEV_SERIAL = "serial"
|
||||
DEV_PARALLEL = "parallel"
|
||||
DEV_CONSOLE = "console"
|
||||
DEV_CHANNEL = "channel"
|
||||
dev_types = [DEV_SERIAL, DEV_PARALLEL, DEV_CONSOLE, DEV_CHANNEL]
|
||||
TYPE_PTY = "pty"
|
||||
TYPE_DEV = "dev"
|
||||
TYPE_STDIO = "stdio"
|
||||
TYPE_PIPE = "pipe"
|
||||
TYPE_FILE = "file"
|
||||
TYPE_VC = "vc"
|
||||
TYPE_NULL = "null"
|
||||
TYPE_TCP = "tcp"
|
||||
TYPE_UDP = "udp"
|
||||
TYPE_UNIX = "unix"
|
||||
TYPE_SPICEVMC = "spicevmc"
|
||||
TYPES = [TYPE_PTY, TYPE_DEV, TYPE_STDIO, TYPE_FILE, TYPE_VC,
|
||||
TYPE_PIPE, TYPE_NULL, TYPE_TCP, TYPE_UDP, TYPE_UNIX,
|
||||
TYPE_SPICEVMC]
|
||||
|
||||
CHAR_PTY = "pty"
|
||||
CHAR_DEV = "dev"
|
||||
CHAR_STDIO = "stdio"
|
||||
CHAR_PIPE = "pipe"
|
||||
CHAR_FILE = "file"
|
||||
CHAR_VC = "vc"
|
||||
CHAR_NULL = "null"
|
||||
CHAR_TCP = "tcp"
|
||||
CHAR_UDP = "udp"
|
||||
CHAR_UNIX = "unix"
|
||||
CHAR_SPICEVMC = "spicevmc"
|
||||
char_types = [CHAR_PTY, CHAR_DEV, CHAR_STDIO, CHAR_FILE, CHAR_VC,
|
||||
CHAR_PIPE, CHAR_NULL, CHAR_TCP, CHAR_UDP, CHAR_UNIX,
|
||||
CHAR_SPICEVMC]
|
||||
MODE_CONNECT = "connect"
|
||||
MODE_BIND = "bind"
|
||||
MODES = [MODE_CONNECT, MODE_BIND]
|
||||
|
||||
_non_channel_types = char_types[:]
|
||||
_non_channel_types.remove(CHAR_SPICEVMC)
|
||||
PROTOCOL_RAW = "raw"
|
||||
PROTOCOL_TELNET = "telnet"
|
||||
PROTOCOLS = [PROTOCOL_RAW, PROTOCOL_TELNET]
|
||||
|
||||
char_types_for_dev_type = {
|
||||
DEV_SERIAL: _non_channel_types,
|
||||
DEV_PARALLEL: _non_channel_types,
|
||||
DEV_CONSOLE: _non_channel_types,
|
||||
DEV_CHANNEL: [CHAR_SPICEVMC],
|
||||
}
|
||||
CHANNEL_TARGET_GUESTFWD = "guestfwd"
|
||||
CHANNEL_TARGET_VIRTIO = "virtio"
|
||||
CHANNEL_TARGETS = [CHANNEL_TARGET_GUESTFWD,
|
||||
CHANNEL_TARGET_VIRTIO]
|
||||
|
||||
CHAR_MODE_CONNECT = "connect"
|
||||
CHAR_MODE_BIND = "bind"
|
||||
char_modes = [CHAR_MODE_CONNECT, CHAR_MODE_BIND]
|
||||
CONSOLE_TARGET_SERIAL = "serial"
|
||||
CONSOLE_TARGET_UML = "uml"
|
||||
CONSOLE_TARGET_XEN = "xen"
|
||||
CONSOLE_TARGET_VIRTIO = "virtio"
|
||||
CONSOLE_TARGETS = [CONSOLE_TARGET_SERIAL, CONSOLE_TARGET_UML,
|
||||
CONSOLE_TARGET_XEN, CONSOLE_TARGET_VIRTIO]
|
||||
|
||||
CHAR_PROTOCOL_RAW = "raw"
|
||||
CHAR_PROTOCOL_TELNET = "telnet"
|
||||
char_protocols = [CHAR_PROTOCOL_RAW, CHAR_PROTOCOL_TELNET]
|
||||
|
||||
CHAR_CHANNEL_TARGET_GUESTFWD = "guestfwd"
|
||||
CHAR_CHANNEL_TARGET_VIRTIO = "virtio"
|
||||
target_types = [CHAR_CHANNEL_TARGET_GUESTFWD,
|
||||
CHAR_CHANNEL_TARGET_VIRTIO]
|
||||
|
||||
CHAR_CHANNEL_ADDRESS_VIRTIO_SERIAL = "virtio-serial"
|
||||
address_types = [CHAR_CHANNEL_ADDRESS_VIRTIO_SERIAL]
|
||||
|
||||
CHAR_CONSOLE_TARGET_SERIAL = "serial"
|
||||
CHAR_CONSOLE_TARGET_UML = "uml"
|
||||
CHAR_CONSOLE_TARGET_XEN = "xen"
|
||||
CHAR_CONSOLE_TARGET_VIRTIO = "virtio"
|
||||
|
||||
has_target = False
|
||||
|
||||
def get_char_type_desc(char_type):
|
||||
@staticmethod
|
||||
def pretty_type(ctype):
|
||||
"""
|
||||
Return a human readable description of the passed char type
|
||||
"""
|
||||
desc = ""
|
||||
|
||||
if char_type == VirtualCharDevice.CHAR_PTY:
|
||||
if ctype == _VirtualCharDevice.TYPE_PTY:
|
||||
desc = _("Pseudo TTY")
|
||||
elif char_type == VirtualCharDevice.CHAR_DEV:
|
||||
elif ctype == _VirtualCharDevice.TYPE_DEV:
|
||||
desc = _("Physical host character device")
|
||||
elif char_type == VirtualCharDevice.CHAR_STDIO:
|
||||
elif ctype == _VirtualCharDevice.TYPE_STDIO:
|
||||
desc = _("Standard input/output")
|
||||
elif char_type == VirtualCharDevice.CHAR_PIPE:
|
||||
elif ctype == _VirtualCharDevice.TYPE_PIPE:
|
||||
desc = _("Named pipe")
|
||||
elif char_type == VirtualCharDevice.CHAR_FILE:
|
||||
elif ctype == _VirtualCharDevice.TYPE_FILE:
|
||||
desc = _("Output to a file")
|
||||
elif char_type == VirtualCharDevice.CHAR_VC:
|
||||
elif ctype == _VirtualCharDevice.TYPE_VC:
|
||||
desc = _("Virtual console")
|
||||
elif char_type == VirtualCharDevice.CHAR_NULL:
|
||||
elif ctype == _VirtualCharDevice.TYPE_NULL:
|
||||
desc = _("Null device")
|
||||
elif char_type == VirtualCharDevice.CHAR_TCP:
|
||||
elif ctype == _VirtualCharDevice.TYPE_TCP:
|
||||
desc = _("TCP net console")
|
||||
elif char_type == VirtualCharDevice.CHAR_UDP:
|
||||
elif ctype == _VirtualCharDevice.TYPE_UDP:
|
||||
desc = _("UDP net console")
|
||||
elif char_type == VirtualCharDevice.CHAR_UNIX:
|
||||
elif ctype == _VirtualCharDevice.TYPE_UNIX:
|
||||
desc = _("Unix socket")
|
||||
elif char_type == VirtualCharDevice.CHAR_SPICEVMC:
|
||||
elif ctype == _VirtualCharDevice.TYPE_SPICEVMC:
|
||||
desc = _("Spice agent")
|
||||
|
||||
return desc
|
||||
get_char_type_desc = staticmethod(get_char_type_desc)
|
||||
|
||||
def get_char_mode_desc(char_mode):
|
||||
@staticmethod
|
||||
def pretty_mode(char_mode):
|
||||
"""
|
||||
Return a human readable description of the passed char type
|
||||
"""
|
||||
desc = ""
|
||||
|
||||
if char_mode == VirtualCharDevice.CHAR_MODE_CONNECT:
|
||||
if char_mode == _VirtualCharDevice.MODE_CONNECT:
|
||||
desc = _("Client mode")
|
||||
elif char_mode == VirtualCharDevice.CHAR_MODE_BIND:
|
||||
elif char_mode == _VirtualCharDevice.MODE_BIND:
|
||||
desc = _("Server mode")
|
||||
|
||||
return desc
|
||||
get_char_mode_desc = staticmethod(get_char_mode_desc)
|
||||
|
||||
# 'char_type' of class (must be properly set in subclass)
|
||||
_char_type = None
|
||||
|
||||
def get_dev_instance(conn, dev_type, char_type):
|
||||
"""
|
||||
Set up the class attributes for the passed char_type
|
||||
"""
|
||||
|
||||
# By default, all the possible parameters are enabled for the
|
||||
# device class. We go through here and del() all the ones that
|
||||
# don't apply. This is kind of whacky, but it's nice to to
|
||||
# allow an API user to just use hasattr(obj, paramname) to see
|
||||
# what parameters apply, instead of having to hardcode all that
|
||||
# information.
|
||||
if char_type == VirtualCharDevice.CHAR_PTY:
|
||||
c = VirtualCharPtyDevice
|
||||
elif char_type == VirtualCharDevice.CHAR_STDIO:
|
||||
c = VirtualCharStdioDevice
|
||||
elif char_type == VirtualCharDevice.CHAR_NULL:
|
||||
c = VirtualCharNullDevice
|
||||
elif char_type == VirtualCharDevice.CHAR_VC:
|
||||
c = VirtualCharVcDevice
|
||||
elif char_type == VirtualCharDevice.CHAR_DEV:
|
||||
c = VirtualCharDevDevice
|
||||
elif char_type == VirtualCharDevice.CHAR_FILE:
|
||||
c = VirtualCharFileDevice
|
||||
elif char_type == VirtualCharDevice.CHAR_PIPE:
|
||||
c = VirtualCharPipeDevice
|
||||
elif char_type == VirtualCharDevice.CHAR_TCP:
|
||||
c = VirtualCharTcpDevice
|
||||
elif char_type == VirtualCharDevice.CHAR_UNIX:
|
||||
c = VirtualCharUnixDevice
|
||||
elif char_type == VirtualCharDevice.CHAR_UDP:
|
||||
c = VirtualCharUdpDevice
|
||||
elif char_type == VirtualCharDevice.CHAR_SPICEVMC:
|
||||
c = VirtualCharSpicevmcDevice
|
||||
else:
|
||||
raise ValueError(_("Unknown character device type '%s'.") %
|
||||
char_type)
|
||||
|
||||
if dev_type == VirtualCharDevice.DEV_CONSOLE:
|
||||
return VirtualConsoleDevice(conn)
|
||||
|
||||
return c(conn, dev_type)
|
||||
get_dev_instance = staticmethod(get_dev_instance)
|
||||
|
||||
def __init__(self, conn, dev_type, parsexml=None, parsexmlnode=None):
|
||||
if dev_type not in self.dev_types:
|
||||
raise ValueError(_("Unknown character device type '%s'") % dev_type)
|
||||
self._dev_type = dev_type
|
||||
self._virtual_device_type = self._dev_type
|
||||
|
||||
VirtualDevice.__init__(self, conn, parsexml, parsexmlnode)
|
||||
|
||||
# Init
|
||||
self._source_path = None
|
||||
self._source_mode = self.CHAR_MODE_BIND
|
||||
self._source_host = "127.0.0.1"
|
||||
self._source_port = None
|
||||
self._target_type = None
|
||||
self._target_address = None
|
||||
self._target_port = None
|
||||
self._target_name = None
|
||||
self._bind_host = None
|
||||
self._bind_port = None
|
||||
self._protocol = self.CHAR_PROTOCOL_RAW
|
||||
self._address_type = None
|
||||
|
||||
if self.char_type == self.CHAR_UDP:
|
||||
self._source_mode = self.CHAR_MODE_CONNECT
|
||||
|
||||
if self._is_parse():
|
||||
return
|
||||
|
||||
if not self._char_type:
|
||||
raise ValueError("Must be instantiated through a subclass.")
|
||||
|
||||
self.char_type = self._char_type
|
||||
|
||||
def supports_property(self, propname, ro=False):
|
||||
"""
|
||||
Whether the character dev type supports the passed property name
|
||||
"""
|
||||
users = {
|
||||
"source_path" : [self.CHAR_FILE, self.CHAR_UNIX,
|
||||
self.CHAR_DEV, self.CHAR_PIPE],
|
||||
"source_mode" : [self.CHAR_UNIX, self.CHAR_TCP],
|
||||
"source_host" : [self.CHAR_TCP, self.CHAR_UDP],
|
||||
"source_port" : [self.CHAR_TCP, self.CHAR_UDP],
|
||||
"protocol" : [self.CHAR_TCP],
|
||||
"bind_host" : [self.CHAR_UDP],
|
||||
"bind_port" : [self.CHAR_UDP],
|
||||
"source_path" : [self.TYPE_FILE, self.TYPE_UNIX,
|
||||
self.TYPE_DEV, self.TYPE_PIPE],
|
||||
"source_mode" : [self.TYPE_UNIX, self.TYPE_TCP],
|
||||
"source_host" : [self.TYPE_TCP, self.TYPE_UDP],
|
||||
"source_port" : [self.TYPE_TCP, self.TYPE_UDP],
|
||||
"protocol" : [self.TYPE_TCP],
|
||||
"bind_host" : [self.TYPE_UDP],
|
||||
"bind_port" : [self.TYPE_UDP],
|
||||
}
|
||||
|
||||
if ro:
|
||||
users["source_path"] += [self.CHAR_PTY]
|
||||
users["source_path"] += [self.TYPE_PTY]
|
||||
|
||||
channel_users = {
|
||||
"target_name" : [self.CHAR_CHANNEL_TARGET_VIRTIO],
|
||||
"target_name" : [self.CHANNEL_TARGET_VIRTIO],
|
||||
}
|
||||
|
||||
if users.get(propname):
|
||||
return self.char_type in users[propname]
|
||||
return self.type in users[propname]
|
||||
if channel_users.get(propname):
|
||||
return (self.dev_type == self.DEV_CHANNEL and
|
||||
return (self.virtual_device_type == "channel" and
|
||||
self.target_type in channel_users[propname])
|
||||
return hasattr(self, propname)
|
||||
|
||||
# Properties
|
||||
def get_dev_type(self):
|
||||
return self._dev_type
|
||||
dev_type = property(get_dev_type)
|
||||
|
||||
def get_char_type(self):
|
||||
return self._char_type
|
||||
def set_char_type(self, val):
|
||||
if val not in self.char_types:
|
||||
raise ValueError(_("Unknown character device type '%s'")
|
||||
% val)
|
||||
self._char_type = val
|
||||
char_type = XMLProperty(get_char_type, set_char_type,
|
||||
_XML_PROP_ORDER = ["type",
|
||||
"bind_host", "bind_port",
|
||||
"source_mode", "source_path",
|
||||
"source_host", "source_port",
|
||||
"target_type", "target_name"]
|
||||
|
||||
type = XMLProperty(
|
||||
doc=_("Method used to expose character device in the host."),
|
||||
xpath="./@type")
|
||||
|
||||
# Properties functions used by the various subclasses
|
||||
def get_source_path(self):
|
||||
return self._source_path
|
||||
def set_source_path(self, val):
|
||||
self._source_path = val
|
||||
def _sourcepath_get_xpath(self):
|
||||
return "./source/@path | ./@tty"
|
||||
source_path = XMLProperty(get_source_path, set_source_path,
|
||||
xml_get_xpath=_sourcepath_get_xpath,
|
||||
xpath="./source/@path")
|
||||
source_path = XMLProperty(xml_get_xpath=_sourcepath_get_xpath,
|
||||
doc=_("Host input path to attach to the guest."),
|
||||
xpath="./source/@path")
|
||||
|
||||
def get_source_mode(self):
|
||||
return self._source_mode
|
||||
def set_source_mode(self, val):
|
||||
if val not in self.char_modes:
|
||||
raise ValueError(_("Unknown character mode '%s'.") % val)
|
||||
self._source_mode = val
|
||||
def _get_default_source_mode(self):
|
||||
if self.type == self.TYPE_UDP:
|
||||
return self.MODE_CONNECT
|
||||
if not self.supports_property("source_mode"):
|
||||
return None
|
||||
return self.MODE_BIND
|
||||
def _sourcemode_xpath(self):
|
||||
if self.char_type == self.CHAR_UDP:
|
||||
if self.type == self.TYPE_UDP:
|
||||
return "./source[@mode='connect']/@mode"
|
||||
return "./source/@mode"
|
||||
source_mode = XMLProperty(get_source_mode, set_source_mode,
|
||||
name="char sourcemode",
|
||||
xml_get_xpath=_sourcemode_xpath,
|
||||
xml_set_xpath=_sourcemode_xpath)
|
||||
source_mode = XMLProperty(name="char sourcemode",
|
||||
doc=_("Target connect/listen mode."),
|
||||
xml_get_xpath=_sourcemode_xpath,
|
||||
xml_set_xpath=_sourcemode_xpath,
|
||||
default_cb=_get_default_source_mode)
|
||||
|
||||
def get_source_host(self):
|
||||
return self._source_host
|
||||
def set_source_host(self, val):
|
||||
self._source_host = val
|
||||
def _get_default_sourcehost(self):
|
||||
if not self.supports_property("source_host"):
|
||||
return None
|
||||
return "127.0.0.1"
|
||||
def _set_source_validate(self, val):
|
||||
if val is None or self.type != self.TYPE_UDP:
|
||||
return val
|
||||
if not self._has_mode_connect:
|
||||
self._has_mode_connect = self.MODE_CONNECT
|
||||
return val
|
||||
def _sourcehost_xpath(self):
|
||||
return "./source[@mode='%s']/@host" % self.source_mode
|
||||
source_host = XMLProperty(get_source_host, set_source_host,
|
||||
name="char sourcehost",
|
||||
xml_get_xpath=_sourcehost_xpath,
|
||||
xml_set_xpath=_sourcehost_xpath)
|
||||
mode = self.source_mode
|
||||
if self.type == self.TYPE_UDP:
|
||||
mode = "connect"
|
||||
return "./source[@mode='%s']/@host" % mode
|
||||
source_host = XMLProperty(name="char sourcehost",
|
||||
doc=_("Address to connect/listen to."),
|
||||
xml_get_xpath=_sourcehost_xpath,
|
||||
xml_set_xpath=_sourcehost_xpath,
|
||||
default_cb=_get_default_sourcehost,
|
||||
set_converter=_set_source_validate)
|
||||
|
||||
def get_source_port(self):
|
||||
return self._source_port
|
||||
def set_source_port(self, val):
|
||||
self._source_port = int(val)
|
||||
def _sourceport_xpath(self):
|
||||
return "./source[@mode='%s']/@service" % self.source_mode
|
||||
source_port = XMLProperty(get_source_port, set_source_port,
|
||||
name="char sourceport",
|
||||
xml_get_xpath=_sourceport_xpath,
|
||||
xml_set_xpath=_sourceport_xpath)
|
||||
def _get_sourceport_convert(self, val):
|
||||
if val is None:
|
||||
return None
|
||||
return int(val)
|
||||
def _set_sourceport_convert(self, val):
|
||||
return self._get_sourceport_convert(self._set_source_validate(val))
|
||||
source_port = XMLProperty(name="char sourceport",
|
||||
doc=_("Port on target host to connect/listen to."),
|
||||
xml_get_xpath=_sourceport_xpath,
|
||||
xml_set_xpath=_sourceport_xpath,
|
||||
set_converter=_set_sourceport_convert,
|
||||
get_converter=_get_sourceport_convert)
|
||||
|
||||
def get_bind_host(self):
|
||||
return self._bind_host
|
||||
def set_bind_host(self, val):
|
||||
self._bind_host = val
|
||||
bind_host = XMLProperty(get_bind_host, set_bind_host,
|
||||
xpath="./source[@mode='bind']/@host")
|
||||
_has_mode_connect = XMLProperty(xpath="./source[@mode='connect']/@mode")
|
||||
_has_mode_bind = XMLProperty(xpath="./source[@mode='bind']/@mode")
|
||||
|
||||
def get_bind_port(self):
|
||||
return self._bind_port
|
||||
def set_bind_port(self, val):
|
||||
self._bind_port = int(val)
|
||||
bind_port = XMLProperty(get_bind_port, set_bind_port,
|
||||
xpath="./source[@mode='bind']/@service")
|
||||
def _set_bind_validate(self, val):
|
||||
if val is None:
|
||||
return None
|
||||
if not self._has_mode_bind:
|
||||
self._has_mode_bind = self.MODE_BIND
|
||||
return val
|
||||
bind_host = XMLProperty(xpath="./source[@mode='bind']/@host",
|
||||
doc=_("Host addresss to bind to."),
|
||||
set_converter=_set_bind_validate)
|
||||
def _get_bindport_convert(self, val):
|
||||
if val is None:
|
||||
return None
|
||||
return int(val)
|
||||
def _set_bindport_convert(self, val):
|
||||
return self._get_bindport_convert(self._set_bind_validate(val))
|
||||
bind_port = XMLProperty(xpath="./source[@mode='bind']/@service",
|
||||
doc=_("Host port to bind to."),
|
||||
get_converter=_get_bindport_convert,
|
||||
set_converter=_set_bindport_convert)
|
||||
|
||||
def get_protocol(self):
|
||||
return self._protocol
|
||||
def set_protocol(self, val):
|
||||
if val not in self.char_protocols:
|
||||
raise ValueError(_("Unknown protocol '%s'.") % val)
|
||||
self._protocol = val
|
||||
protocol = XMLProperty(get_protocol, set_protocol,
|
||||
xpath="./protocol/@type")
|
||||
def _get_default_protocol(self):
|
||||
if not self.supports_property("protocol"):
|
||||
return None
|
||||
return self.PROTOCOL_RAW
|
||||
protocol = XMLProperty(xpath="./protocol/@type",
|
||||
doc=_("Format used when sending data."),
|
||||
default_cb=_get_default_protocol)
|
||||
|
||||
# GuestFWD target properties
|
||||
def get_target_type(self):
|
||||
return self._target_type
|
||||
def set_target_type(self, val):
|
||||
if val not in self.target_types:
|
||||
raise ValueError(_("Unknown target type '%s'. Must be in: ") % val,
|
||||
self.target_types)
|
||||
self._target_type = val
|
||||
target_type = XMLProperty(get_target_type, set_target_type,
|
||||
doc=_("Channel type as exposed in the guest."),
|
||||
xpath="./target/@type")
|
||||
def _get_default_target_type(self):
|
||||
if self.type == self.TYPE_SPICEVMC:
|
||||
return self.CHANNEL_TARGET_VIRTIO
|
||||
return None
|
||||
target_type = XMLProperty(xpath="./target/@type",
|
||||
doc=_("Channel type as exposed in the guest."),
|
||||
default_cb=_get_default_target_type)
|
||||
|
||||
def set_target_address(self, val):
|
||||
self._target_address = val
|
||||
def get_target_address(self):
|
||||
return self._target_address
|
||||
target_address = XMLProperty(get_target_address, set_target_address,
|
||||
doc=_("Guest forward channel address in the guest."),
|
||||
xpath="./target/@address")
|
||||
target_address = XMLProperty(xpath="./target/@address",
|
||||
doc=_("Guest forward channel address in the guest."))
|
||||
|
||||
def set_target_port(self, val):
|
||||
self._target_port = val
|
||||
def get_target_port(self):
|
||||
return self._target_port
|
||||
target_port = XMLProperty(get_target_port, set_target_port,
|
||||
doc=_("Guest forward channel port in the guest."),
|
||||
xpath="./target/@port")
|
||||
target_port = XMLProperty(xpath="./target/@port", is_int=True,
|
||||
doc=_("Guest forward channel port in the guest."))
|
||||
|
||||
def set_target_name(self, val):
|
||||
self._target_name = val
|
||||
def get_target_name(self):
|
||||
return self._target_name
|
||||
target_name = XMLProperty(get_target_name, set_target_name,
|
||||
def _default_target_name(self):
|
||||
if self.type == self.TYPE_SPICEVMC:
|
||||
return "com.redhat.spice.0"
|
||||
return None
|
||||
target_name = XMLProperty(xpath="./target/@name",
|
||||
doc=_("Sysfs name of virtio port in the guest"),
|
||||
xpath="./target/@name")
|
||||
|
||||
def get_address_type(self):
|
||||
return self._address_type
|
||||
def set_address_type(self, val):
|
||||
if val not in self.address_types:
|
||||
raise ValueError(_("Unknown address type '%s'. Must be in: ") % val,
|
||||
self.address_types)
|
||||
self._address_type = val
|
||||
address_type = XMLProperty(get_address_type, set_address_type,
|
||||
doc=_("Channel type as exposed in the guest."),
|
||||
xpath="./address/@type")
|
||||
|
||||
# XML building helpers
|
||||
def _char_empty_xml(self):
|
||||
"""
|
||||
Provide source xml for devices with no params (null, stdio, ...)
|
||||
"""
|
||||
return ""
|
||||
|
||||
def _char_file_xml(self):
|
||||
"""
|
||||
Provide source xml for devs that require only a path (dev, pipe)
|
||||
"""
|
||||
file_xml = ""
|
||||
mode_xml = ""
|
||||
if self.source_path:
|
||||
file_xml = " path='%s'" % xml_escape(self.source_path)
|
||||
else:
|
||||
raise ValueError(_("A source path is required for character "
|
||||
"device type '%s'" % self.char_type))
|
||||
|
||||
if self.supports_property("source_mode") and self.source_mode:
|
||||
mode_xml = " mode='%s'" % xml_escape(self.source_mode)
|
||||
|
||||
xml = " <source%s%s/>\n" % (mode_xml, file_xml)
|
||||
return xml
|
||||
|
||||
def _char_xml(self):
|
||||
pass
|
||||
|
||||
def _get_target_xml(self):
|
||||
xml = ""
|
||||
if not self.target_type:
|
||||
return xml
|
||||
|
||||
xml = " <target type='%s'" % self.target_type
|
||||
|
||||
if self._dev_type == self.DEV_CHANNEL:
|
||||
if self.target_type == self.CHAR_CHANNEL_TARGET_GUESTFWD:
|
||||
if not self.target_address and not self.target_port:
|
||||
raise RuntimeError("A target address and port must be "
|
||||
"specified for '%s'" % self.target_type)
|
||||
|
||||
xml += " address='%s'" % self.target_address
|
||||
xml += " port='%s'" % self.target_port
|
||||
|
||||
elif self.target_type == self.CHAR_CHANNEL_TARGET_VIRTIO:
|
||||
if self.target_name:
|
||||
xml += " name='%s'" % self.target_name
|
||||
default_cb=_default_target_name)
|
||||
|
||||
|
||||
xml += "/>\n"
|
||||
return xml
|
||||
|
||||
def _get_address_xml(self):
|
||||
xml = ""
|
||||
if not self.address_type:
|
||||
return xml
|
||||
|
||||
xml = " <address type='%s'" % self.address_type
|
||||
xml += "/>\n"
|
||||
return xml
|
||||
class VirtualConsoleDevice(_VirtualCharDevice):
|
||||
virtual_device_type = "console"
|
||||
|
||||
|
||||
def _get_xml_config(self):
|
||||
xml = " <%s type='%s'" % (self._dev_type, self._char_type)
|
||||
char_xml = self._char_xml()
|
||||
target_xml = self._get_target_xml()
|
||||
has_target = (self._dev_type == self.DEV_CHANNEL or
|
||||
self._dev_type == self.DEV_CONSOLE or
|
||||
self.has_target)
|
||||
|
||||
if target_xml and not has_target:
|
||||
raise RuntimeError(
|
||||
"Target parameters not used with '%s' devices, only '%s'" %
|
||||
(self._dev_type, self.DEV_CHANNEL))
|
||||
|
||||
address_xml = self._get_address_xml()
|
||||
has_address = self._target_type == self.CHAR_CHANNEL_TARGET_VIRTIO
|
||||
if address_xml and not has_address:
|
||||
raise RuntimeError(
|
||||
"Address parameters not used with '%s' target, only '%s'" %
|
||||
(self._target_type, self.CHAR_CHANNEL_TARGET_VIRTIO))
|
||||
|
||||
if char_xml or target_xml or address_xml:
|
||||
xml += ">"
|
||||
if char_xml:
|
||||
xml += "\n%s" % char_xml
|
||||
|
||||
if target_xml:
|
||||
xml += "\n%s" % target_xml
|
||||
|
||||
if address_xml:
|
||||
xml += "\n%s" % target_xml
|
||||
|
||||
xml += " </%s>" % self._dev_type
|
||||
else:
|
||||
xml += "/>"
|
||||
|
||||
return xml
|
||||
|
||||
# Back compat class for building a simple PTY 'console' element
|
||||
class VirtualSerialDevice(_VirtualCharDevice):
|
||||
virtual_device_type = "serial"
|
||||
|
||||
|
||||
class VirtualConsoleDevice(VirtualCharDevice):
|
||||
_char_xml = VirtualCharDevice._char_empty_xml
|
||||
_char_type = VirtualCharDevice.CHAR_PTY
|
||||
|
||||
def __init__(self, conn, parsexml=None, parsexmlnode=None):
|
||||
VirtualCharDevice.__init__(self, conn, VirtualCharDevice.DEV_CONSOLE,
|
||||
parsexml, parsexmlnode)
|
||||
|
||||
self.target_types = [self.CHAR_CONSOLE_TARGET_SERIAL,
|
||||
self.CHAR_CONSOLE_TARGET_VIRTIO,
|
||||
self.CHAR_CONSOLE_TARGET_XEN,
|
||||
self.CHAR_CONSOLE_TARGET_UML]
|
||||
|
||||
# Classes for each device 'type'
|
||||
class VirtualParallelDevice(_VirtualCharDevice):
|
||||
virtual_device_type = "parallel"
|
||||
|
||||
|
||||
class VirtualCharPtyDevice(VirtualCharDevice):
|
||||
_char_type = VirtualCharDevice.CHAR_PTY
|
||||
_char_xml = VirtualCharDevice._char_empty_xml
|
||||
source_path = property(VirtualCharDevice.get_source_path,
|
||||
VirtualCharDevice.set_source_path,
|
||||
doc=_("PTY allocated to the guest."))
|
||||
|
||||
|
||||
class VirtualCharStdioDevice(VirtualCharDevice):
|
||||
_char_type = VirtualCharDevice.CHAR_STDIO
|
||||
_char_xml = VirtualCharDevice._char_empty_xml
|
||||
|
||||
|
||||
class VirtualCharNullDevice(VirtualCharDevice):
|
||||
_char_type = VirtualCharDevice.CHAR_NULL
|
||||
_char_xml = VirtualCharDevice._char_empty_xml
|
||||
|
||||
|
||||
class VirtualCharVcDevice(VirtualCharDevice):
|
||||
_char_type = VirtualCharDevice.CHAR_VC
|
||||
_char_xml = VirtualCharDevice._char_empty_xml
|
||||
|
||||
|
||||
class VirtualCharDevDevice(VirtualCharDevice):
|
||||
_char_type = VirtualCharDevice.CHAR_DEV
|
||||
_char_xml = VirtualCharDevice._char_file_xml
|
||||
source_path = property(VirtualCharDevice.get_source_path,
|
||||
VirtualCharDevice.set_source_path,
|
||||
doc=_("Host character device to attach to guest."))
|
||||
|
||||
|
||||
class VirtualCharPipeDevice(VirtualCharDevice):
|
||||
_char_type = VirtualCharDevice.CHAR_PIPE
|
||||
_char_xml = VirtualCharDevice._char_file_xml
|
||||
source_path = property(VirtualCharDevice.get_source_path,
|
||||
VirtualCharDevice.set_source_path,
|
||||
doc=_("Named pipe to use for input and output."))
|
||||
|
||||
|
||||
class VirtualCharFileDevice(VirtualCharDevice):
|
||||
_char_type = VirtualCharDevice.CHAR_FILE
|
||||
_char_xml = VirtualCharDevice._char_file_xml
|
||||
source_path = property(VirtualCharDevice.get_source_path,
|
||||
VirtualCharDevice.set_source_path,
|
||||
doc=_("File path to record device output."))
|
||||
|
||||
|
||||
class VirtualCharUnixDevice(VirtualCharDevice):
|
||||
_char_type = VirtualCharDevice.CHAR_UNIX
|
||||
_char_xml = VirtualCharDevice._char_file_xml
|
||||
|
||||
source_mode = property(VirtualCharDevice.get_source_mode,
|
||||
VirtualCharDevice.set_source_mode,
|
||||
doc=_("Target connect/listen mode."))
|
||||
source_path = property(VirtualCharDevice.get_source_path,
|
||||
VirtualCharDevice.set_source_path,
|
||||
doc=_("Unix socket path."))
|
||||
|
||||
|
||||
class VirtualCharTcpDevice(VirtualCharDevice):
|
||||
_char_type = VirtualCharDevice.CHAR_TCP
|
||||
|
||||
source_mode = property(VirtualCharDevice.get_source_mode,
|
||||
VirtualCharDevice.set_source_mode,
|
||||
doc=_("Target connect/listen mode."))
|
||||
source_host = property(VirtualCharDevice.get_source_host,
|
||||
VirtualCharDevice.set_source_host,
|
||||
doc=_("Address to connect/listen to."))
|
||||
source_port = property(VirtualCharDevice.get_source_port,
|
||||
VirtualCharDevice.set_source_port,
|
||||
doc=_("Port on target host to connect/listen to."))
|
||||
protocol = property(VirtualCharDevice.get_protocol,
|
||||
VirtualCharDevice.set_protocol,
|
||||
doc=_("Format used when sending data."))
|
||||
|
||||
def _char_xml(self):
|
||||
if not self.source_host and not self.source_port:
|
||||
raise ValueError(_("A host and port must be specified."))
|
||||
|
||||
xml = (" <source mode='%s' host='%s' service='%s'/>\n" %
|
||||
(self.source_mode, self.source_host, self.source_port))
|
||||
xml += " <protocol type='%s'/>\n" % self.protocol
|
||||
return xml
|
||||
|
||||
|
||||
class VirtualCharUdpDevice(VirtualCharDevice):
|
||||
_char_type = VirtualCharDevice.CHAR_UDP
|
||||
|
||||
bind_host = property(VirtualCharDevice.get_bind_host,
|
||||
VirtualCharDevice.set_bind_host,
|
||||
doc=_("Host address to bind to."))
|
||||
bind_port = property(VirtualCharDevice.get_bind_port,
|
||||
VirtualCharDevice.set_bind_port,
|
||||
doc=_("Host port to bind to."))
|
||||
source_host = property(VirtualCharDevice.get_source_host,
|
||||
VirtualCharDevice.set_source_host,
|
||||
doc=_("Host address to send output to."))
|
||||
source_port = property(VirtualCharDevice.get_source_port,
|
||||
VirtualCharDevice.set_source_port,
|
||||
doc=_("Host port to send output to."))
|
||||
|
||||
# XXX: UDP: Only source _connect_ port required?
|
||||
def _char_xml(self):
|
||||
if not self.source_port:
|
||||
raise ValueError(_("A connection port must be specified."))
|
||||
|
||||
xml = ""
|
||||
bind_xml = ""
|
||||
bind_host_xml = ""
|
||||
bind_port_xml = ""
|
||||
source_host_xml = ""
|
||||
|
||||
if self.bind_port:
|
||||
bind_port_xml = " service='%s'" % self.bind_port
|
||||
if not self.bind_host:
|
||||
self.bind_host = "127.0.0.1"
|
||||
if self.bind_host:
|
||||
bind_host_xml = " host='%s'" % self.bind_host
|
||||
if self.source_host:
|
||||
source_host_xml = " host='%s'" % self.source_host
|
||||
|
||||
if self.bind_host or self.bind_port:
|
||||
bind_xml = (" <source mode='bind'%s%s/>\n" %
|
||||
(bind_host_xml, bind_port_xml))
|
||||
|
||||
xml += bind_xml
|
||||
xml += (" <source mode='connect'%s service='%s'/>\n" %
|
||||
(source_host_xml, self.source_port))
|
||||
return xml
|
||||
|
||||
|
||||
class VirtualCharSpicevmcDevice(VirtualCharDevice):
|
||||
_char_type = VirtualCharDevice.CHAR_SPICEVMC
|
||||
_char_xml = VirtualCharDevice._char_empty_xml
|
||||
target_types = [VirtualCharDevice.CHAR_CHANNEL_TARGET_VIRTIO]
|
||||
has_target = True
|
||||
|
||||
def __init__(self, conn, dev_type=VirtualCharDevice.DEV_CHANNEL,
|
||||
parsexml=None, parsexmlnode=None):
|
||||
VirtualCharDevice.__init__(self, conn, dev_type,
|
||||
parsexml, parsexmlnode)
|
||||
self._target_type = VirtualCharDevice.CHAR_CHANNEL_TARGET_VIRTIO
|
||||
self._target_name = "com.redhat.spice.0"
|
||||
class VirtualChannelDevice(_VirtualCharDevice):
|
||||
virtual_device_type = "channel"
|
||||
TYPES = [_VirtualCharDevice.TYPE_SPICEVMC]
|
||||
|
|
|
@ -22,7 +22,7 @@ from virtinst.xmlbuilder import XMLProperty
|
|||
|
||||
|
||||
class VirtualController(VirtualDevice):
|
||||
_virtual_device_type = VirtualDevice.VIRTUAL_DEV_CONTROLLER
|
||||
virtual_device_type = VirtualDevice.VIRTUAL_DEV_CONTROLLER
|
||||
|
||||
TYPE_IDE = "ide"
|
||||
TYPE_FDC = "fdc"
|
||||
|
|
|
@ -69,7 +69,7 @@ class VirtualDevice(XMLBuilder):
|
|||
VIRTUAL_DEV_TPM]
|
||||
|
||||
# General device type (disk, interface, etc.)
|
||||
_virtual_device_type = None
|
||||
virtual_device_type = None
|
||||
_XML_INDENT = 4
|
||||
|
||||
def __init__(self, conn, parsexml=None, parsexmlnode=None):
|
||||
|
@ -79,24 +79,20 @@ class VirtualDevice(XMLBuilder):
|
|||
@param conn: libvirt connection to validate device against
|
||||
"""
|
||||
XMLBuilder.__init__(self, conn, parsexml, parsexmlnode)
|
||||
self._XML_ROOT_NAME = self._virtual_device_type
|
||||
self._XML_ROOT_NAME = self.virtual_device_type
|
||||
|
||||
self.alias = VirtualDeviceAlias(conn, parsexmlnode=parsexmlnode)
|
||||
self.address = VirtualDeviceAddress(conn, parsexmlnode=parsexmlnode)
|
||||
self._XML_SUB_ELEMENTS = ["alias", "address"]
|
||||
|
||||
if not self._virtual_device_type:
|
||||
if not self.virtual_device_type:
|
||||
raise ValueError(_("Virtual device type must be set in subclass."))
|
||||
|
||||
if self._virtual_device_type not in self.virtual_device_types:
|
||||
if self.virtual_device_type not in self.virtual_device_types:
|
||||
raise ValueError(_("Unknown virtual device type '%s'.") %
|
||||
self._virtual_device_type)
|
||||
self.virtual_device_type)
|
||||
|
||||
|
||||
def get_virtual_device_type(self):
|
||||
return self._virtual_device_type
|
||||
virtual_device_type = property(get_virtual_device_type)
|
||||
|
||||
def setup(self, meter=None):
|
||||
"""
|
||||
Perform potentially hazardous device initialization, like
|
||||
|
|
|
@ -142,7 +142,7 @@ class VirtualDisk(VirtualDevice):
|
|||
# pylint: disable=W0622
|
||||
# Redefining built-in 'type', but it matches the XML so keep it
|
||||
|
||||
_virtual_device_type = VirtualDevice.VIRTUAL_DEV_DISK
|
||||
virtual_device_type = VirtualDevice.VIRTUAL_DEV_DISK
|
||||
|
||||
DRIVER_FILE = "file"
|
||||
DRIVER_PHY = "phy"
|
||||
|
|
|
@ -24,7 +24,7 @@ from virtinst.xmlbuilder import XMLProperty
|
|||
|
||||
|
||||
class VirtualFilesystem(VirtualDevice):
|
||||
_virtual_device_type = VirtualDevice.VIRTUAL_DEV_FILESYSTEM
|
||||
virtual_device_type = VirtualDevice.VIRTUAL_DEV_FILESYSTEM
|
||||
|
||||
_target_props = ["dir", "name", "file", "dev"]
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ def _yes_bool(val):
|
|||
|
||||
|
||||
class VirtualGraphics(VirtualDevice):
|
||||
_virtual_device_type = VirtualDevice.VIRTUAL_DEV_GRAPHICS
|
||||
virtual_device_type = VirtualDevice.VIRTUAL_DEV_GRAPHICS
|
||||
|
||||
TYPE_SDL = "sdl"
|
||||
TYPE_VNC = "vnc"
|
||||
|
|
|
@ -23,7 +23,7 @@ from virtinst import NodeDeviceParser
|
|||
|
||||
|
||||
class VirtualHostDevice(VirtualDevice):
|
||||
_virtual_device_type = VirtualDevice.VIRTUAL_DEV_HOSTDEV
|
||||
virtual_device_type = VirtualDevice.VIRTUAL_DEV_HOSTDEV
|
||||
|
||||
@staticmethod
|
||||
def device_from_node(conn, name=None, nodedev=None, is_dup=False,
|
||||
|
|
|
@ -22,7 +22,7 @@ from virtinst.xmlbuilder import XMLProperty
|
|||
|
||||
|
||||
class VirtualInputDevice(VirtualDevice):
|
||||
_virtual_device_type = VirtualDevice.VIRTUAL_DEV_INPUT
|
||||
virtual_device_type = VirtualDevice.VIRTUAL_DEV_INPUT
|
||||
|
||||
TYPE_MOUSE = "mouse"
|
||||
TYPE_TABLET = "tablet"
|
||||
|
|
|
@ -22,7 +22,7 @@ from virtinst.xmlbuilder import XMLProperty
|
|||
|
||||
|
||||
class VirtualMemballoon(VirtualDevice):
|
||||
_virtual_device_type = VirtualDevice.VIRTUAL_DEV_MEMBALLOON
|
||||
virtual_device_type = VirtualDevice.VIRTUAL_DEV_MEMBALLOON
|
||||
|
||||
MODEL_DEFAULT = "virtio"
|
||||
MODELS = ["xen", "none", MODEL_DEFAULT]
|
||||
|
|
|
@ -66,7 +66,7 @@ class VirtualPort(XMLBuilder):
|
|||
|
||||
class VirtualNetworkInterface(VirtualDevice):
|
||||
|
||||
_virtual_device_type = VirtualDevice.VIRTUAL_DEV_NET
|
||||
virtual_device_type = VirtualDevice.VIRTUAL_DEV_NET
|
||||
|
||||
TYPE_BRIDGE = "bridge"
|
||||
TYPE_VIRTUAL = "network"
|
||||
|
|
|
@ -26,7 +26,7 @@ from virtinst.xmlbuilder import XMLProperty
|
|||
|
||||
class VirtualRedirDevice(VirtualDevice):
|
||||
|
||||
_virtual_device_type = VirtualDevice.VIRTUAL_DEV_REDIRDEV
|
||||
virtual_device_type = VirtualDevice.VIRTUAL_DEV_REDIRDEV
|
||||
|
||||
BUS_DEFAULT = "default"
|
||||
BUSES = ["usb"]
|
||||
|
|
|
@ -25,7 +25,7 @@ from virtinst.xmlbuilder import XMLProperty
|
|||
|
||||
class VirtualSmartCardDevice(VirtualDevice):
|
||||
|
||||
_virtual_device_type = VirtualDevice.VIRTUAL_DEV_SMARTCARD
|
||||
virtual_device_type = VirtualDevice.VIRTUAL_DEV_SMARTCARD
|
||||
|
||||
# Default models list
|
||||
MODE_DEFAULT = "default"
|
||||
|
|
|
@ -28,7 +28,7 @@ from virtinst.xmlbuilder import XMLProperty
|
|||
|
||||
class VirtualTPMDevice(VirtualDevice):
|
||||
|
||||
_virtual_device_type = VirtualDevice.VIRTUAL_DEV_TPM
|
||||
virtual_device_type = VirtualDevice.VIRTUAL_DEV_TPM
|
||||
|
||||
TYPE_PASSTHROUGH = "passthrough"
|
||||
TYPE_DEFAULT = "default"
|
||||
|
|
|
@ -23,7 +23,7 @@ from virtinst.xmlbuilder import XMLProperty
|
|||
|
||||
class VirtualVideoDevice(VirtualDevice):
|
||||
|
||||
_virtual_device_type = VirtualDevice.VIRTUAL_DEV_VIDEO
|
||||
virtual_device_type = VirtualDevice.VIRTUAL_DEV_VIDEO
|
||||
|
||||
# Default models list
|
||||
MODEL_DEFAULT = "default"
|
||||
|
|
|
@ -23,7 +23,7 @@ from virtinst.xmlbuilder import XMLProperty
|
|||
|
||||
class VirtualWatchdog(VirtualDevice):
|
||||
|
||||
_virtual_device_type = VirtualDevice.VIRTUAL_DEV_WATCHDOG
|
||||
virtual_device_type = VirtualDevice.VIRTUAL_DEV_WATCHDOG
|
||||
|
||||
MODEL_I6300 = "i6300esb"
|
||||
MODEL_IB700 = "ib700"
|
||||
|
|
|
@ -28,7 +28,10 @@ from virtinst.VirtualAudio import VirtualAudio
|
|||
from virtinst.VirtualInputDevice import VirtualInputDevice
|
||||
from virtinst.VirtualDisk import VirtualDisk
|
||||
from virtinst.VirtualHostDevice import VirtualHostDevice
|
||||
from virtinst.VirtualCharDevice import VirtualCharDevice
|
||||
from virtinst.VirtualCharDevice import (VirtualChannelDevice,
|
||||
VirtualConsoleDevice,
|
||||
VirtualParallelDevice,
|
||||
VirtualSerialDevice)
|
||||
from virtinst.VirtualVideoDevice import VirtualVideoDevice
|
||||
from virtinst.VirtualController import VirtualController
|
||||
from virtinst.VirtualWatchdog import VirtualWatchdog
|
||||
|
|
|
@ -42,7 +42,6 @@ from virtinst import VirtualNetworkInterface
|
|||
from virtinst import VirtualGraphics
|
||||
from virtinst import VirtualAudio
|
||||
from virtinst import VirtualDisk
|
||||
from virtinst import VirtualCharDevice
|
||||
|
||||
|
||||
DEFAULT_POOL_PATH = "/var/lib/libvirt/images"
|
||||
|
@ -1813,32 +1812,36 @@ def parse_memballoon(guest, optstring, dev=None):
|
|||
######################################################
|
||||
|
||||
def parse_serial(guest, optstring, dev=None):
|
||||
return _parse_char(guest, optstring, "serial", dev)
|
||||
if not dev:
|
||||
dev = virtinst.VirtualSerialDevice(guest.conn)
|
||||
return _parse_char(optstring, "serial", dev)
|
||||
|
||||
|
||||
def parse_parallel(guest, optstring, dev=None):
|
||||
return _parse_char(guest, optstring, "parallel", dev)
|
||||
if not dev:
|
||||
dev = virtinst.VirtualParallelDevice(guest.conn)
|
||||
return _parse_char(optstring, "parallel", dev)
|
||||
|
||||
|
||||
def parse_console(guest, optstring, dev=None):
|
||||
return _parse_char(guest, optstring, "console", dev)
|
||||
if not dev:
|
||||
dev = virtinst.VirtualConsoleDevice(guest.conn)
|
||||
return _parse_char(optstring, "console", dev)
|
||||
|
||||
|
||||
def parse_channel(guest, optstring, dev=None):
|
||||
return _parse_char(guest, optstring, "channel", dev)
|
||||
if not dev:
|
||||
dev = virtinst.VirtualChannelDevice(guest.conn)
|
||||
return _parse_char(optstring, "channel", dev)
|
||||
|
||||
|
||||
def _parse_char(guest, optstring, dev_type, dev=None):
|
||||
def _parse_char(optstring, dev_type, dev=None):
|
||||
"""
|
||||
Helper to parse --serial/--parallel options
|
||||
"""
|
||||
# Peel the char type off the front
|
||||
opts = parse_optstr(optstring, remove_first="char_type")
|
||||
char_type = opts.get("char_type")
|
||||
|
||||
if not dev:
|
||||
dev = VirtualCharDevice.get_dev_instance(guest.conn,
|
||||
dev_type, char_type)
|
||||
ctype = opts.get("char_type")
|
||||
|
||||
def set_param(paramname, dictname, val=None):
|
||||
val = get_opt_param(opts, dictname, val)
|
||||
|
@ -1848,7 +1851,7 @@ def _parse_char(guest, optstring, dev_type, dev=None):
|
|||
if not dev.supports_property(paramname):
|
||||
raise ValueError(_("%(devtype)s type '%(chartype)s' does not "
|
||||
"support '%(optname)s' option.") %
|
||||
{"devtype" : dev_type, "chartype": char_type,
|
||||
{"devtype" : dev_type, "chartype": ctype,
|
||||
"optname" : dictname})
|
||||
setattr(dev, paramname, val)
|
||||
|
||||
|
@ -1863,7 +1866,7 @@ def _parse_char(guest, optstring, dev_type, dev=None):
|
|||
bind_host, bind_port = parse_host("bind_host")
|
||||
target_addr, target_port = parse_host("target_address")
|
||||
|
||||
set_param("char_type", "char_type")
|
||||
set_param("type", "char_type")
|
||||
set_param("source_path", "path")
|
||||
set_param("source_mode", "mode")
|
||||
set_param("protocol", "protocol")
|
||||
|
|
|
@ -313,8 +313,8 @@ class XMLProperty(property):
|
|||
raise RuntimeError("Can't set default_cb for old style XML "
|
||||
"prop.")
|
||||
|
||||
property.__init__(self, fget=self.new_getter, fset=self.new_setter,
|
||||
doc=doc)
|
||||
property.__init__(self, fget=self.new_getter, fset=self.new_setter)
|
||||
self.__doc__ = doc
|
||||
|
||||
|
||||
##################
|
||||
|
@ -344,7 +344,7 @@ class XMLProperty(property):
|
|||
Map the raw property() instance to the param name it's exposed
|
||||
as in the XMLBuilder class. This is just for debug purposes.
|
||||
"""
|
||||
for key, val in xmlbuilder._all_xml_props().items():
|
||||
for key, val in xmlbuilder.all_xml_props().items():
|
||||
if val is self:
|
||||
return key
|
||||
raise RuntimeError("Didn't find expected property")
|
||||
|
@ -703,7 +703,7 @@ class XMLBuilder(object):
|
|||
Refresh the XML for the passed class propname. Used to adjust
|
||||
the XML when an interdependent property changes.
|
||||
"""
|
||||
self._all_xml_props()[propname].refresh_xml(self)
|
||||
self.all_xml_props()[propname].refresh_xml(self)
|
||||
|
||||
|
||||
###################
|
||||
|
@ -772,7 +772,7 @@ class XMLBuilder(object):
|
|||
|
||||
self._set_xml_context()
|
||||
|
||||
def _all_xml_props(self):
|
||||
def all_xml_props(self):
|
||||
ret = {}
|
||||
for c in reversed(type.mro(self.__class__)[:-1]):
|
||||
for key, val in c.__dict__.items():
|
||||
|
@ -782,7 +782,7 @@ class XMLBuilder(object):
|
|||
|
||||
def _do_add_parse_bits(self, xml):
|
||||
# Find all properties that have default callbacks
|
||||
xmlprops = self._all_xml_props()
|
||||
xmlprops = self.all_xml_props()
|
||||
defaultprops = [v for v in xmlprops.values() if v.has_default_value()]
|
||||
for prop in defaultprops:
|
||||
prop.set_default(self)
|
||||
|
|
Loading…
Reference in New Issue