Support viewing and removing VM 'video' devices.

This commit is contained in:
Cole Robinson 2009-07-09 14:35:55 -04:00
parent 79f3e9987e
commit 10be2d2a45
3 changed files with 1053 additions and 862 deletions

View File

@ -61,12 +61,13 @@ HW_LIST_TYPE_GRAPHICS = 8
HW_LIST_TYPE_SOUND = 9 HW_LIST_TYPE_SOUND = 9
HW_LIST_TYPE_CHAR = 10 HW_LIST_TYPE_CHAR = 10
HW_LIST_TYPE_HOSTDEV = 11 HW_LIST_TYPE_HOSTDEV = 11
HW_LIST_TYPE_VIDEO = 12
apply_pages = [ HW_LIST_TYPE_GENERAL, HW_LIST_TYPE_CPU, HW_LIST_TYPE_MEMORY, apply_pages = [ HW_LIST_TYPE_GENERAL, HW_LIST_TYPE_CPU, HW_LIST_TYPE_MEMORY,
HW_LIST_TYPE_BOOT] HW_LIST_TYPE_BOOT]
remove_pages = [ HW_LIST_TYPE_DISK, HW_LIST_TYPE_NIC, HW_LIST_TYPE_INPUT, remove_pages = [ HW_LIST_TYPE_DISK, HW_LIST_TYPE_NIC, HW_LIST_TYPE_INPUT,
HW_LIST_TYPE_GRAPHICS, HW_LIST_TYPE_SOUND, HW_LIST_TYPE_CHAR, HW_LIST_TYPE_GRAPHICS, HW_LIST_TYPE_SOUND, HW_LIST_TYPE_CHAR,
HW_LIST_TYPE_HOSTDEV ] HW_LIST_TYPE_HOSTDEV, HW_LIST_TYPE_VIDEO ]
# Console pages # Console pages
PAGE_UNAVAILABLE = 0 PAGE_UNAVAILABLE = 0
@ -693,6 +694,8 @@ class vmmDetails(gobject.GObject):
self.refresh_char_page() self.refresh_char_page()
elif pagetype == HW_LIST_TYPE_HOSTDEV: elif pagetype == HW_LIST_TYPE_HOSTDEV:
self.refresh_hostdev_page() self.refresh_hostdev_page()
elif pagetype == HW_LIST_TYPE_VIDEO:
self.refresh_video_page()
else: else:
pagetype = -1 pagetype = -1
@ -1142,6 +1145,20 @@ class vmmDetails(gobject.GObject):
self.window.get_widget("hostdev-mode").set_text(hostdevinfo[3]) self.window.get_widget("hostdev-mode").set_text(hostdevinfo[3])
self.window.get_widget("hostdev-source").set_text(hostdevinfo[5]) self.window.get_widget("hostdev-source").set_text(hostdevinfo[5])
def refresh_video_page(self):
vidinfo = self.get_hw_selection(HW_LIST_COL_DEVICE)
if not vidinfo:
return
ignore, ignore, model, ram, heads = vidinfo
try:
ramlabel = ram and "%d MB" % (int(ram) / 1024) or "-"
except:
ramlabel = "-"
self.window.get_widget("video-model").set_text(model)
self.window.get_widget("video-ram").set_text(ramlabel)
self.window.get_widget("video-heads").set_text(heads and heads or "-")
def refresh_boot_page(self): def refresh_boot_page(self):
# Refresh autostart # Refresh autostart
@ -1743,6 +1760,7 @@ class vmmDetails(gobject.GObject):
currentSounds = {} currentSounds = {}
currentChars = {} currentChars = {}
currentHostdevs = {} currentHostdevs = {}
currentVids = {}
def update_hwlist(hwtype, info): def update_hwlist(hwtype, info):
"""Return (true if we updated an entry, """Return (true if we updated an entry,
@ -1843,6 +1861,17 @@ class vmmDetails(gobject.GObject):
if missing: if missing:
hw_list_model.insert(insertAt, [hostdevinfo[2], None, gtk.ICON_SIZE_LARGE_TOOLBAR, None, HW_LIST_TYPE_HOSTDEV, hostdevinfo]) hw_list_model.insert(insertAt, [hostdevinfo[2], None, gtk.ICON_SIZE_LARGE_TOOLBAR, None, HW_LIST_TYPE_HOSTDEV, hostdevinfo])
# Populate video devices
for vidinfo in self.vm.get_video_devices():
currentVids[vidinfo[2]] = 1
missing, insertAt = update_hwlist(HW_LIST_TYPE_VIDEO,
vidinfo)
if missing:
hw_list_model.insert(insertAt,
[_("Video"), gtk.STOCK_SELECT_COLOR,
gtk.ICON_SIZE_LARGE_TOOLBAR,
None, HW_LIST_TYPE_VIDEO, vidinfo])
# Now remove any no longer current devs # Now remove any no longer current devs
devs = range(len(hw_list_model)) devs = range(len(hw_list_model))
@ -1852,26 +1881,21 @@ class vmmDetails(gobject.GObject):
row = hw_list_model[i] row = hw_list_model[i]
removeIt = False removeIt = False
if row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_DISK and not \ mapping = {
currentDisks.has_key(row[HW_LIST_COL_DEVICE][2]): HW_LIST_TYPE_DISK : currentDisks,
removeIt = True HW_LIST_TYPE_NIC : currentNICs,
elif row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_NIC and not \ HW_LIST_TYPE_INPUT : currentInputs,
currentNICs.has_key(row[HW_LIST_COL_DEVICE][2]): HW_LIST_TYPE_GRAPHICS : currentGraphics,
removeIt = True HW_LIST_TYPE_SOUND : currentSounds,
elif row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_INPUT and not \ HW_LIST_TYPE_CHAR : currentChars,
currentInputs.has_key(row[HW_LIST_COL_DEVICE][2]): HW_LIST_TYPE_HOSTDEV : currentHostdevs,
removeIt = True HW_LIST_TYPE_VIDEO : currentVids,
elif row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_GRAPHICS and not \ }
currentGraphics.has_key(row[HW_LIST_COL_DEVICE][2]):
removeIt = True
elif row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_SOUND and not \ hwtype = row[HW_LIST_COL_TYPE]
currentSounds.has_key(row[HW_LIST_COL_DEVICE][2]): if (mapping.has_key(hwtype) and not
removeIt = True mapping[hwtype].has_key(row[HW_LIST_COL_DEVICE][2])):
elif row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_CHAR and not \
currentChars.has_key(row[HW_LIST_COL_DEVICE][2]):
removeIt = True
elif row[HW_LIST_COL_TYPE] == HW_LIST_TYPE_HOSTDEV and not \
currentHostdevs.has_key(row[HW_LIST_COL_DEVICE][2]):
removeIt = True removeIt = True
if removeIt: if removeIt:
@ -1880,7 +1904,8 @@ class vmmDetails(gobject.GObject):
(selModel, selIter) = hw_list.get_selection().get_selected() (selModel, selIter) = hw_list.get_selection().get_selected()
selType = selModel.get_value(selIter, HW_LIST_COL_TYPE) selType = selModel.get_value(selIter, HW_LIST_COL_TYPE)
selInfo = selModel.get_value(selIter, HW_LIST_COL_DEVICE) selInfo = selModel.get_value(selIter, HW_LIST_COL_DEVICE)
if selType == row[HW_LIST_COL_TYPE] and selInfo[2] == row[HW_LIST_COL_DEVICE][2]: if (selType == row[HW_LIST_COL_TYPE] and
selInfo[2] == row[HW_LIST_COL_DEVICE][2]):
hw_list.get_selection().select_iter(selModel.iter_nth_child(None, 0)) hw_list.get_selection().select_iter(selModel.iter_nth_child(None, 0))
# Now actually remove it # Now actually remove it

View File

@ -28,6 +28,13 @@ import difflib
from virtManager import util from virtManager import util
import virtinst.util as vutil import virtinst.util as vutil
def safeint(val, fmt="%.3d"):
try:
int(val)
except:
return str(val)
return fmt % int(val)
class vmmDomain(gobject.GObject): class vmmDomain(gobject.GObject):
__gsignals__ = { __gsignals__ = {
"status-changed": (gobject.SIGNAL_RUN_FIRST, "status-changed": (gobject.SIGNAL_RUN_FIRST,
@ -932,6 +939,32 @@ class vmmDomain(gobject.GObject):
return self._parse_device_xml(_parse_char_devs) return self._parse_device_xml(_parse_char_devs)
def get_video_devices(self):
def _parse_video_devs(ctx):
vids = []
devs = ctx.xpathEval("/domain/devices/video")
for dev in devs:
model = None
ram = None
heads = None
for node in dev.children or []:
if node.name == "model":
model = node.prop("type")
ram = node.prop("vram")
heads = node.prop("heads")
if ram:
ram = safeint(ram, "%d")
unique = [model, ram, heads]
row = ["video", unique, model, ram, heads]
vids.append(row)
return vids
return self._parse_device_xml(_parse_video_devs)
def get_hostdev_devices(self): def get_hostdev_devices(self):
def _parse_hostdev_devs(ctx): def _parse_hostdev_devs(ctx):
hostdevs = [] hostdevs = []
@ -954,13 +987,6 @@ class vmmDomain(gobject.GObject):
val = val[2:] val = val[2:]
return val return val
def safeint(val, fmt="%.3d"):
try:
int(val)
except:
return str(val)
return fmt % int(val)
def set_uniq(baseent, propname, node): def set_uniq(baseent, propname, node):
val = node.prop(propname) val = node.prop(propname)
if not unique.has_key(baseent): if not unique.has_key(baseent):
@ -1028,15 +1054,10 @@ class vmmDomain(gobject.GObject):
def _parse_device_xml(self, parse_function): def _parse_device_xml(self, parse_function):
ret = []
def parse_wrap_func(doc, ctx): def parse_wrap_func(doc, ctx):
return parse_function(ctx) return parse_function(ctx)
try: return util.xml_parse_wrapper(self.get_xml(), parse_wrap_func)
ret = util.xml_parse_wrapper(self.get_xml(), parse_wrap_func)
except Exception, e:
raise RuntimeError(_("Error parsing domain xml: %s") % str(e))
return ret
def _add_xml_device(self, xml, devxml): def _add_xml_device(self, xml, devxml):
""" """
@ -1136,6 +1157,19 @@ class vmmDomain(gobject.GObject):
logging.debug("Hostdev xpath string: %s" % xpath) logging.debug("Hostdev xpath string: %s" % xpath)
ret = ctx.xpathEval(xpath) ret = ctx.xpathEval(xpath)
elif dev_type == "video":
model, ram, heads = dev_id_info
xpath = "/domain/devices/video"
xpath += "[model/@type='%s'" % model
if ram:
xpath += " and model/@vram='%s'" % ram
if heads:
xpath += " and model/@heads='%s'" % heads
xpath += "][1]"
ret = ctx.xpathEval(xpath)
else: else:
raise RuntimeError, _("Unknown device type '%s'" % dev_type) raise RuntimeError, _("Unknown device type '%s'" % dev_type)

File diff suppressed because it is too large Load Diff