From e802eae07b1dad9a3956e9f2894483d2ee231996 Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Tue, 16 Jul 2013 09:14:37 -0400 Subject: [PATCH] VirtualCharDevice: Convert to new style XML props, rework API --- tests/xmlconfig.py | 69 +-- tests/xmlparse-xml/change-chars-out.xml | 5 +- tests/xmlparse.py | 28 +- virt-install | 14 +- virtManager/addhardware.py | 61 ++- virtManager/details.py | 10 +- virtManager/domain.py | 20 +- virtManager/serialcon.py | 2 +- virtinst/Guest.py | 27 +- virtinst/VirtualAudio.py | 2 +- virtinst/VirtualCharDevice.py | 691 ++++++------------------ virtinst/VirtualController.py | 2 +- virtinst/VirtualDevice.py | 14 +- virtinst/VirtualDisk.py | 2 +- virtinst/VirtualFilesystem.py | 2 +- virtinst/VirtualGraphics.py | 2 +- virtinst/VirtualHostDevice.py | 2 +- virtinst/VirtualInputDevice.py | 2 +- virtinst/VirtualMemballoon.py | 2 +- virtinst/VirtualNetworkInterface.py | 2 +- virtinst/VirtualRedirDevice.py | 2 +- virtinst/VirtualSmartCardDevice.py | 2 +- virtinst/VirtualTPMDevice.py | 2 +- virtinst/VirtualVideoDevice.py | 2 +- virtinst/VirtualWatchdog.py | 2 +- virtinst/__init__.py | 5 +- virtinst/cli.py | 29 +- virtinst/xmlbuilder.py | 12 +- 28 files changed, 325 insertions(+), 690 deletions(-) diff --git a/tests/xmlconfig.py b/tests/xmlconfig.py index aafecb94..7e78acea 100644 --- a/tests/xmlconfig.py +++ b/tests/xmlconfig.py @@ -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) diff --git a/tests/xmlparse-xml/change-chars-out.xml b/tests/xmlparse-xml/change-chars-out.xml index 1dd0e88c..9f94987a 100644 --- a/tests/xmlparse-xml/change-chars-out.xml +++ b/tests/xmlparse-xml/change-chars-out.xml @@ -20,7 +20,10 @@ /usr/lib/xen/bin/qemu-dm - + + + + diff --git a/tests/xmlparse.py b/tests/xmlparse.py index 70870f22..2ecc506b 100644 --- a/tests/xmlparse.py +++ b/tests/xmlparse.py @@ -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) diff --git a/virt-install b/virt-install index 6faff9d5..ab447dd2 100755 --- a/virt-install +++ b/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) diff --git a/virtManager/addhardware.py b/virtManager/addhardware.py index 85699650..1ac79510 100644 --- a/virtManager/addhardware.py +++ b/virtManager/addhardware.py @@ -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 = "%s" 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() diff --git a/virtManager/details.py b/virtManager/details.py index 9b7062a4..0bd1baed 100644 --- a/virtManager/details.py +++ b/virtManager/details.py @@ -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 = "" diff --git a/virtManager/domain.py b/virtManager/domain.py index d2178bf1..34e881a3 100644 --- a/virtManager/domain.py +++ b/virtManager/domain.py @@ -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) diff --git a/virtManager/serialcon.py b/virtManager/serialcon.py index f569a869..18769527 100644 --- a/virtManager/serialcon.py +++ b/virtManager/serialcon.py @@ -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) diff --git a/virtinst/Guest.py b/virtinst/Guest.py index 6bb03563..6a11bcc2 100644 --- a/virtinst/Guest.py +++ b/virtinst/Guest.py @@ -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 diff --git a/virtinst/VirtualAudio.py b/virtinst/VirtualAudio.py index edb74c59..13b51423 100644 --- a/virtinst/VirtualAudio.py +++ b/virtinst/VirtualAudio.py @@ -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] diff --git a/virtinst/VirtualCharDevice.py b/virtinst/VirtualCharDevice.py index ad99199c..3a78976c 100644 --- a/virtinst/VirtualCharDevice.py +++ b/virtinst/VirtualCharDevice.py @@ -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 = " \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 = " \n" % - (self.source_mode, self.source_host, self.source_port)) - xml += " \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 = (" \n" % - (bind_host_xml, bind_port_xml)) - - xml += bind_xml - xml += (" \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] diff --git a/virtinst/VirtualController.py b/virtinst/VirtualController.py index 08ef7c4a..99636866 100644 --- a/virtinst/VirtualController.py +++ b/virtinst/VirtualController.py @@ -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" diff --git a/virtinst/VirtualDevice.py b/virtinst/VirtualDevice.py index 57037135..6b037469 100644 --- a/virtinst/VirtualDevice.py +++ b/virtinst/VirtualDevice.py @@ -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 diff --git a/virtinst/VirtualDisk.py b/virtinst/VirtualDisk.py index e4325e72..2ac23068 100644 --- a/virtinst/VirtualDisk.py +++ b/virtinst/VirtualDisk.py @@ -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" diff --git a/virtinst/VirtualFilesystem.py b/virtinst/VirtualFilesystem.py index 87521397..94755c43 100644 --- a/virtinst/VirtualFilesystem.py +++ b/virtinst/VirtualFilesystem.py @@ -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"] diff --git a/virtinst/VirtualGraphics.py b/virtinst/VirtualGraphics.py index 0dc0f88e..bb84c605 100644 --- a/virtinst/VirtualGraphics.py +++ b/virtinst/VirtualGraphics.py @@ -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" diff --git a/virtinst/VirtualHostDevice.py b/virtinst/VirtualHostDevice.py index 404c8f46..374a49ac 100644 --- a/virtinst/VirtualHostDevice.py +++ b/virtinst/VirtualHostDevice.py @@ -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, diff --git a/virtinst/VirtualInputDevice.py b/virtinst/VirtualInputDevice.py index a4fa28c6..28e00e8c 100644 --- a/virtinst/VirtualInputDevice.py +++ b/virtinst/VirtualInputDevice.py @@ -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" diff --git a/virtinst/VirtualMemballoon.py b/virtinst/VirtualMemballoon.py index adb3aab3..1edb72c5 100644 --- a/virtinst/VirtualMemballoon.py +++ b/virtinst/VirtualMemballoon.py @@ -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] diff --git a/virtinst/VirtualNetworkInterface.py b/virtinst/VirtualNetworkInterface.py index cb1e7661..e02d88d6 100644 --- a/virtinst/VirtualNetworkInterface.py +++ b/virtinst/VirtualNetworkInterface.py @@ -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" diff --git a/virtinst/VirtualRedirDevice.py b/virtinst/VirtualRedirDevice.py index 98830107..aefa32e6 100644 --- a/virtinst/VirtualRedirDevice.py +++ b/virtinst/VirtualRedirDevice.py @@ -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"] diff --git a/virtinst/VirtualSmartCardDevice.py b/virtinst/VirtualSmartCardDevice.py index 8a583455..0a11eb6a 100644 --- a/virtinst/VirtualSmartCardDevice.py +++ b/virtinst/VirtualSmartCardDevice.py @@ -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" diff --git a/virtinst/VirtualTPMDevice.py b/virtinst/VirtualTPMDevice.py index 8964b5b4..b99290ad 100644 --- a/virtinst/VirtualTPMDevice.py +++ b/virtinst/VirtualTPMDevice.py @@ -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" diff --git a/virtinst/VirtualVideoDevice.py b/virtinst/VirtualVideoDevice.py index 76143fbc..97138940 100644 --- a/virtinst/VirtualVideoDevice.py +++ b/virtinst/VirtualVideoDevice.py @@ -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" diff --git a/virtinst/VirtualWatchdog.py b/virtinst/VirtualWatchdog.py index 819f83a8..ada5febf 100644 --- a/virtinst/VirtualWatchdog.py +++ b/virtinst/VirtualWatchdog.py @@ -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" diff --git a/virtinst/__init__.py b/virtinst/__init__.py index 1695789d..006b2641 100644 --- a/virtinst/__init__.py +++ b/virtinst/__init__.py @@ -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 diff --git a/virtinst/cli.py b/virtinst/cli.py index 9ec62c6a..9d49efe5 100644 --- a/virtinst/cli.py +++ b/virtinst/cli.py @@ -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") diff --git a/virtinst/xmlbuilder.py b/virtinst/xmlbuilder.py index 78bb47b6..049ae230 100644 --- a/virtinst/xmlbuilder.py +++ b/virtinst/xmlbuilder.py @@ -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)