domain: Use virtinst for char device listing

This commit is contained in:
Cole Robinson 2010-09-03 17:56:40 -04:00
parent f52d5c8b3a
commit f0cb7c964e
2 changed files with 63 additions and 131 deletions

View File

@ -640,7 +640,7 @@ class vmmDetails(gobject.GObject):
devs = self.vm.get_serial_devs() devs = self.vm.get_serial_devs()
if len(devs) == 0: if len(devs) == 0:
item = gtk.MenuItem(_("No serial devices found")) item = gtk.MenuItem(_("No text console available"))
item.set_sensitive(False) item.set_sensitive(False)
src.add(item) src.add(item)
@ -688,18 +688,20 @@ class vmmDetails(gobject.GObject):
devs = self.vm.get_graphics_devices() devs = self.vm.get_graphics_devices()
if len(devs) == 0: if len(devs) == 0:
item = gtk.MenuItem(_("No graphics console found.")) item = gtk.MenuItem(_("No graphical console available"))
item.set_sensitive(False) item.set_sensitive(False)
src.add(item) src.add(item)
else: else:
dev = devs[0] dev = devs[0]
item = gtk.RadioMenuItem(group, _("Graphical Console %s") % dev[2]) item = gtk.RadioMenuItem(group, _("Graphical Console %s") %
dev.type.upper())
if group == None: if group == None:
group = item group = item
if on_graphics: if on_graphics:
item.set_active(True) item.set_active(True)
item.connect("toggled", self.control_serial_tab, dev[0], dev[2]) item.connect("toggled", self.control_serial_tab,
dev.virtual_device_type, dev.type)
src.add(item) src.add(item)
src.show_all() src.show_all()
@ -1940,19 +1942,19 @@ class vmmDetails(gobject.GObject):
self.set_combo_label("sound-model", 0, sound.model) self.set_combo_label("sound-model", 0, sound.model)
def refresh_char_page(self): def refresh_char_page(self):
charinfo = self.get_hw_selection(HW_LIST_COL_DEVICE) chardev = self.get_hw_selection(HW_LIST_COL_DEVICE)
if not charinfo: if not chardev:
return return
char_type = charinfo[0].capitalize() char_type = chardev.virtual_device_type.capitalize()
target_port = charinfo[3] target_port = chardev.index
dev_type = charinfo[4] or "pty" dev_type = chardev.char_type or "pty"
src_path = charinfo[5] src_path = chardev.source_path
primary = charinfo[6] primary = hasattr(chardev, "console_dup")
typelabel = "%s Device" % char_type typelabel = "%s Device" % char_type
if target_port: if target_port is not None:
typelabel += " %s" % target_port typelabel += " %s" % (int(target_port) + 1)
if primary: if primary:
typelabel += " (%s)" % _("Primary Console") typelabel += " (%s)" % _("Primary Console")
typelabel = "<b>%s</b>" % typelabel typelabel = "<b>%s</b>" % typelabel
@ -2215,18 +2217,19 @@ class vmmDetails(gobject.GObject):
_("Sound: %s" % model), "audio-card", key) _("Sound: %s" % model), "audio-card", key)
# Populate list of char devices # Populate list of char devices
for charinfo in self.vm.get_char_devices(): for chardev in self.vm.get_char_devices():
key = str(charinfo[1]) devtype = chardev.virtual_device_type
devtype = charinfo[0] port = chardev.index
port = charinfo[3] key = str(devtype + ":" + str(port))
currentChars[key] = 1 currentChars[key] = 1
label = devtype.capitalize() label = devtype.capitalize()
if devtype != "console": if devtype != "console":
# Don't show port for console # Don't show port for console
label += " %s" % (int(port) + 1) label += " %s" % (int(port) + 1)
update_hwlist(HW_LIST_TYPE_CHAR, charinfo, label, update_hwlist(HW_LIST_TYPE_CHAR, chardev, label,
"device_serial", key) "device_serial", key)
# Populate host devices # Populate host devices

View File

@ -317,66 +317,35 @@ class vmmDomainBase(vmmLibvirtObject):
# Device listing # Device listing
def get_serial_devs(self): def get_serial_devs(self):
def _parse_serial_consoles(ctx): devs = self.get_char_devices()
# [ Name, device type, source path devlist = []
serial_list = []
sdevs = ctx.xpathEval("/domain/devices/serial")
cdevs = ctx.xpathEval("/domain/devices/console")
for node in sdevs:
name = "Serial "
dev_type = node.prop("type")
source_path = None
for child in node.children: serials = filter(lambda x: x.virtual_device_type == "serial", devs)
if child.name == "target": consoles = filter(lambda x: x.virtual_device_type == "console", devs)
target_port = child.prop("port")
if target_port:
name += str(target_port)
if child.name == "source":
source_path = child.prop("path")
serial_list.append([name, dev_type, source_path, target_port]) for dev in serials:
devlist.append(["Serial %s" % (dev.index + 1), dev.char_type,
dev.source_path, dev.index])
for node in cdevs: for dev in consoles:
name = "Serial Console" devlist.append(["Text Console %s" % (dev.index + 1),
dev_type = "pty" dev.char_type, dev.source_path, dev.index])
source_path = None
target_port = -1
inuse = False
for child in node.children: return devlist
if child.name == "source":
source_path = child.prop("path")
if child.name == "target":
target_port = child.prop("port")
if target_port != -1:
for dev in serial_list:
if target_port == dev[3]:
inuse = True
break
if not inuse:
serial_list.append([name, dev_type, source_path,
target_port])
return serial_list
return self._parse_device_xml(_parse_serial_consoles)
def get_graphics_console(self): def get_graphics_console(self):
gtype = vutil.get_xml_path(self.get_xml(), gdevs = self.get_graphics_devices()
"/domain/devices/graphics/@type")
vncport = vutil.get_xml_path(self.get_xml(),
"/domain/devices/graphics[@type='vnc']/@port")
if gtype != "vnc":
vncport = None
else:
vncport = int(vncport)
connhost = self.connection.get_uri_hostname() connhost = self.connection.get_uri_hostname()
transport, username = self.connection.get_transport() transport, username = self.connection.get_transport()
vncport = None
gport = None
gtype = None
if gdevs:
gport = gdevs[0].port
gtype = gdevs[0].type
if gtype == 'vnc':
vncport = int(gport)
if connhost == None: if connhost == None:
# Force use of 127.0.0.1, because some (broken) systems don't # Force use of 127.0.0.1, because some (broken) systems don't
@ -392,7 +361,7 @@ class vmmDomainBase(vmmLibvirtObject):
# Build VNC uri for debugging # Build VNC uri for debugging
vncuri = None vncuri = None
if gtype: if gtype == 'vnc':
vncuri = str(gtype) + "://" vncuri = str(gtype) + "://"
if username: if username:
vncuri = vncuri + str(username) + '@' vncuri = vncuri + str(username) + '@'
@ -402,12 +371,6 @@ class vmmDomainBase(vmmLibvirtObject):
vncuri] vncuri]
# ----------------
# get_X_devices functions: return a list of lists. Each sublist represents
# a device, of the format:
# [ device_type, unique_attribute(s), hw column label, attr1, attr2, ... ]
# ----------------
def get_disk_devices(self, refresh_if_necc=True, inactive=False): def get_disk_devices(self, refresh_if_necc=True, inactive=False):
device_type = "disk" device_type = "disk"
guest = self._get_guest(refresh_if_necc=refresh_if_necc, guest = self._get_guest(refresh_if_necc=refresh_if_necc,
@ -466,66 +429,32 @@ class vmmDomainBase(vmmLibvirtObject):
return devs return devs
def get_char_devices(self): def get_char_devices(self):
def _parse_char_devs(ctx): devs = []
chars = [] guest = self._get_guest()
devs = []
devs.extend(ctx.xpathEval("/domain/devices/console"))
devs.extend(ctx.xpathEval("/domain/devices/parallel"))
devs.extend(ctx.xpathEval("/domain/devices/serial"))
# Since there is only one 'console' device ever in the xml serials = guest.get_devices("serial")
# find its port (if present) and path parallels = guest.get_devices("parallel")
cons_port = None consoles = guest.get_devices("console")
cons_dev = None
list_cons = True
count_dict = {}
for node in devs: for devicelist in [serials, parallels, consoles]:
char_type = node.name count = 0
dev_type = node.prop("type") for dev in devicelist:
target_port = None dev.index = count
source_path = None count += 1
for child in node.children or []: devs.extend(devicelist)
if child.name == "source":
source_path = child.prop("path")
if not source_path: # Don't display <console> if it's just a duplicate of <serial>
source_path = node.prop("tty") if (len(consoles) > 0 and len(serials) > 0):
con = consoles[0]
ser = serials[0]
# Rather than parse the target port, just calculate it if (con.char_type == ser.char_type and
# ourselves. This helps device removal when customizing con.target_type is None or con.target_type == "serial"):
# installs ser.console_dup = True
if count_dict.get(char_type) == None: devs.remove(con)
count_dict[char_type] = -1
count_dict[char_type] += 1
target_port = str(count_dict[char_type])
# [device type, unique, display string, target_port, return devs
# char device type, source_path, is_console_dup_of_serial?
disp = "%s:%s" % (char_type, target_port)
dev = [char_type, disp, disp, target_port,
dev_type, source_path, False]
if node.name == "console":
cons_port = target_port
cons_dev = dev
dev[6] = True
continue
elif node.name == "serial" and cons_port \
and target_port == cons_port:
# Console is just a dupe of this serial device
dev[6] = True
list_cons = False
chars.append(dev)
if cons_dev and list_cons:
chars.append(cons_dev)
return chars
return self._parse_device_xml(_parse_char_devs)
def get_video_devices(self): def get_video_devices(self):
device_type = "video" device_type = "video"