mirror of
https://github.com/virt-manager/virt-manager.git
synced 2024-10-27 10:25:25 +03:00
details: Use VirtualDevice instance as the HW row key
Allows us to do lots of cleanup and simplifications. Domain now moves around dev instances rather than device lookup info (dev_id_info).
This commit is contained in:
parent
6eee79a88f
commit
e8f346733d
@ -32,7 +32,8 @@ class vmmChooseCD(gobject.GObject):
|
||||
__gsignals__ = {
|
||||
"cdrom-chosen": (gobject.SIGNAL_RUN_FIRST,
|
||||
gobject.TYPE_NONE,
|
||||
(str, str, str)), # type, source, target
|
||||
# dev, source, target
|
||||
(gobject.TYPE_PYOBJECT, str, str)),
|
||||
}
|
||||
|
||||
IS_FLOPPY = 1
|
||||
|
@ -43,8 +43,6 @@ HW_LIST_COL_ICON_NAME = 1
|
||||
HW_LIST_COL_ICON_SIZE = 2
|
||||
HW_LIST_COL_TYPE = 3
|
||||
HW_LIST_COL_DEVICE = 4
|
||||
HW_LIST_COL_KEY = 5
|
||||
HW_LIST_COL_DEVTYPE = 6
|
||||
|
||||
# Types for the hw list model: numbers specify what order they will be listed
|
||||
HW_LIST_TYPE_GENERAL = 0
|
||||
@ -571,12 +569,9 @@ class vmmDetails(gobject.GObject):
|
||||
|
||||
def init_details(self):
|
||||
# Hardware list
|
||||
# [ label, icon name, icon size, hw type, hw data, hw key,
|
||||
# dev type name]
|
||||
# [ label, icon name, icon size, hw type, hw data/class]
|
||||
hw_list_model = gtk.ListStore(str, str, int, int,
|
||||
gobject.TYPE_PYOBJECT,
|
||||
gobject.TYPE_PYOBJECT,
|
||||
str)
|
||||
gobject.TYPE_PYOBJECT)
|
||||
self.window.get_widget("hw-list").set_model(hw_list_model)
|
||||
|
||||
hwCol = gtk.TreeViewColumn("Hardware")
|
||||
@ -1035,10 +1030,8 @@ class vmmDetails(gobject.GObject):
|
||||
if not info:
|
||||
return
|
||||
|
||||
devtype = self.get_hw_selection(HW_LIST_COL_DEVTYPE)
|
||||
key = self.get_hw_selection(HW_LIST_COL_KEY)
|
||||
|
||||
self.remove_device(devtype, key)
|
||||
devtype = info.virtual_device_type
|
||||
self.remove_device(devtype, info)
|
||||
|
||||
def control_vm_pause(self, src):
|
||||
if self.ignorePause:
|
||||
@ -1330,7 +1323,7 @@ class vmmDetails(gobject.GObject):
|
||||
if not disk:
|
||||
return
|
||||
|
||||
dev_id_info = disk.target
|
||||
dev_id_info = disk
|
||||
curpath = disk.path
|
||||
devtype = disk.device
|
||||
|
||||
@ -1363,7 +1356,8 @@ class vmmDetails(gobject.GObject):
|
||||
|
||||
def config_apply(self, ignore):
|
||||
pagetype = self.get_hw_selection(HW_LIST_COL_TYPE)
|
||||
key = self.get_hw_selection(HW_LIST_COL_KEY)
|
||||
devobj = self.get_hw_selection(HW_LIST_COL_DEVICE)
|
||||
key = devobj
|
||||
ret = False
|
||||
|
||||
if pagetype is HW_LIST_TYPE_GENERAL:
|
||||
@ -2054,7 +2048,7 @@ class vmmDetails(gobject.GObject):
|
||||
target_port = chardev.index
|
||||
dev_type = chardev.char_type or "pty"
|
||||
src_path = chardev.source_path
|
||||
primary = hasattr(chardev, "console_dup")
|
||||
primary = hasattr(chardev, "virtmanager_console_dup")
|
||||
|
||||
typelabel = "%s Device" % char_type
|
||||
if target_port is not None:
|
||||
@ -2145,7 +2139,7 @@ class vmmDetails(gobject.GObject):
|
||||
def add_hw_list_option(title, page_id, data, icon_name):
|
||||
hw_list_model.append([title, icon_name,
|
||||
gtk.ICON_SIZE_LARGE_TOOLBAR,
|
||||
page_id, data, None, None])
|
||||
page_id, data])
|
||||
|
||||
add_hw_list_option("Overview", HW_LIST_TYPE_GENERAL, [], "computer")
|
||||
if not self.is_customize_dialog:
|
||||
@ -2161,55 +2155,54 @@ class vmmDetails(gobject.GObject):
|
||||
hw_list = self.window.get_widget("hw-list")
|
||||
hw_list_model = hw_list.get_model()
|
||||
|
||||
currentDisks = {}
|
||||
currentNICs = {}
|
||||
currentInputs = {}
|
||||
currentGraphics = {}
|
||||
currentSounds = {}
|
||||
currentChars = {}
|
||||
currentHostdevs = {}
|
||||
currentVids = {}
|
||||
currentWatchdogs = {}
|
||||
currentDevices = []
|
||||
|
||||
def add_hw_list_option(idx, name, page_id, info, icon_name, key, dev):
|
||||
def dev_cmp(origdev, newdev):
|
||||
if not origdev:
|
||||
return False
|
||||
|
||||
if origdev == newdev:
|
||||
return True
|
||||
|
||||
if not origdev.get_xml_node_path():
|
||||
return False
|
||||
|
||||
return origdev.get_xml_node_path() == newdev.get_xml_node_path()
|
||||
|
||||
def add_hw_list_option(idx, name, page_id, info, icon_name):
|
||||
hw_list_model.insert(idx, [name, icon_name,
|
||||
gtk.ICON_SIZE_LARGE_TOOLBAR,
|
||||
page_id, info, key, dev])
|
||||
page_id, info])
|
||||
|
||||
def update_hwlist(hwtype, info, name, icon_name, key):
|
||||
def update_hwlist(hwtype, info, name, icon_name):
|
||||
"""
|
||||
See if passed hw is already in list, and if so, update info.
|
||||
If not in list, add it!
|
||||
"""
|
||||
currentDevices.append(info)
|
||||
|
||||
insertAt = 0
|
||||
for row in hw_list_model:
|
||||
if (row[HW_LIST_COL_TYPE] == hwtype and
|
||||
row[HW_LIST_COL_KEY] == key):
|
||||
|
||||
rowdev = row[HW_LIST_COL_DEVICE]
|
||||
if dev_cmp(rowdev, info):
|
||||
# Update existing HW info
|
||||
row[HW_LIST_COL_DEVICE] = info
|
||||
row[HW_LIST_COL_LABEL] = name
|
||||
row[HW_LIST_COL_ICON_NAME] = icon_name
|
||||
return
|
||||
|
||||
if row[HW_LIST_COL_TYPE] <= hwtype:
|
||||
insertAt += 1
|
||||
|
||||
# Add the new HW row
|
||||
if type(info) is list:
|
||||
devtype = info[0]
|
||||
else:
|
||||
devtype = info.virtual_device_type
|
||||
add_hw_list_option(insertAt, name, hwtype, info, icon_name, key,
|
||||
devtype)
|
||||
add_hw_list_option(insertAt, name, hwtype, info, icon_name)
|
||||
|
||||
# Populate list of disks
|
||||
for disk in self.vm.get_disk_devices():
|
||||
key = disk.target
|
||||
devtype = disk.device
|
||||
bus = disk.bus
|
||||
idx = disk.disk_bus_index
|
||||
|
||||
currentDisks[key] = 1
|
||||
icon = "drive-harddisk"
|
||||
if devtype == "cdrom":
|
||||
icon = "media-optical"
|
||||
@ -2218,23 +2211,19 @@ class vmmDetails(gobject.GObject):
|
||||
|
||||
label = prettyify_disk(devtype, bus, idx)
|
||||
|
||||
update_hwlist(HW_LIST_TYPE_DISK, disk, label, icon, key)
|
||||
update_hwlist(HW_LIST_TYPE_DISK, disk, label, icon)
|
||||
|
||||
# Populate list of NICs
|
||||
for net in self.vm.get_network_devices():
|
||||
key = str(net.macaddr)
|
||||
mac = net.macaddr
|
||||
|
||||
currentNICs[key] = 1
|
||||
update_hwlist(HW_LIST_TYPE_NIC, net,
|
||||
"NIC %s" % mac[-9:], "network-idle", key)
|
||||
"NIC %s" % mac[-9:], "network-idle")
|
||||
|
||||
# Populate list of input devices
|
||||
for inp in self.vm.get_input_devices():
|
||||
key = str("%s:%s" % (inp.type, inp.bus))
|
||||
inptype = inp.type
|
||||
|
||||
currentInputs[key] = 1
|
||||
icon = "input-mouse"
|
||||
if inptype == "tablet":
|
||||
label = _("Tablet")
|
||||
@ -2244,34 +2233,23 @@ class vmmDetails(gobject.GObject):
|
||||
else:
|
||||
label = _("Input")
|
||||
|
||||
update_hwlist(HW_LIST_TYPE_INPUT, inp, label, icon, key)
|
||||
update_hwlist(HW_LIST_TYPE_INPUT, inp, label, icon)
|
||||
|
||||
# Populate list of graphics devices
|
||||
for gfx in self.vm.get_graphics_devices():
|
||||
key = str(gfx.index)
|
||||
gfxtype = gfx.type
|
||||
|
||||
currentGraphics[key] = 1
|
||||
update_hwlist(HW_LIST_TYPE_GRAPHICS, gfx,
|
||||
_("Display %s") % (gfxtype.upper()),
|
||||
"video-display", key)
|
||||
_("Display %s") % (gfx.type.upper()),
|
||||
"video-display")
|
||||
|
||||
# Populate list of sound devices
|
||||
for sound in self.vm.get_sound_devices():
|
||||
key = str(sound.index)
|
||||
model = sound.model
|
||||
|
||||
currentSounds[key] = 1
|
||||
update_hwlist(HW_LIST_TYPE_SOUND, sound,
|
||||
_("Sound: %s" % model), "audio-card", key)
|
||||
_("Sound: %s" % sound.model), "audio-card")
|
||||
|
||||
# Populate list of char devices
|
||||
for chardev in self.vm.get_char_devices():
|
||||
devtype = chardev.virtual_device_type
|
||||
port = chardev.index
|
||||
key = str(devtype + ":" + str(port))
|
||||
|
||||
currentChars[key] = 1
|
||||
|
||||
label = devtype.capitalize()
|
||||
if devtype != "console":
|
||||
@ -2279,75 +2257,38 @@ class vmmDetails(gobject.GObject):
|
||||
label += " %s" % (int(port) + 1)
|
||||
|
||||
update_hwlist(HW_LIST_TYPE_CHAR, chardev, label,
|
||||
"device_serial", key)
|
||||
"device_serial")
|
||||
|
||||
# Populate host devices
|
||||
for hostdev in self.vm.get_hostdev_devices():
|
||||
key = str(hostdev.index)
|
||||
devtype = hostdev.type
|
||||
label = build_hostdev_label(hostdev)[1]
|
||||
|
||||
currentHostdevs[key] = 1
|
||||
if devtype == "usb":
|
||||
icon = "device_usb"
|
||||
else:
|
||||
icon = "device_pci"
|
||||
update_hwlist(HW_LIST_TYPE_HOSTDEV, hostdev, label, icon, key)
|
||||
update_hwlist(HW_LIST_TYPE_HOSTDEV, hostdev, label, icon)
|
||||
|
||||
# Populate video devices
|
||||
for vid in self.vm.get_video_devices():
|
||||
key = str(vid.index)
|
||||
|
||||
currentVids[key] = 1
|
||||
update_hwlist(HW_LIST_TYPE_VIDEO, vid, _("Video"),
|
||||
"video-display", key)
|
||||
update_hwlist(HW_LIST_TYPE_VIDEO, vid, _("Video"), "video-display")
|
||||
|
||||
for watch in self.vm.get_watchdog_devices():
|
||||
key = str(watch.index)
|
||||
|
||||
currentWatchdogs[key] = 1
|
||||
update_hwlist(HW_LIST_TYPE_WATCHDOG, watch, _("Watchdog"),
|
||||
"device_pci", key)
|
||||
"device_pci")
|
||||
|
||||
# Now remove any no longer current devs
|
||||
devs = range(len(hw_list_model))
|
||||
devs.reverse()
|
||||
for i in devs:
|
||||
_iter = hw_list_model.iter_nth_child(None, i)
|
||||
row = hw_list_model[i]
|
||||
removeIt = False
|
||||
olddev = hw_list_model[i][HW_LIST_COL_DEVICE]
|
||||
|
||||
mapping = {
|
||||
HW_LIST_TYPE_DISK : currentDisks,
|
||||
HW_LIST_TYPE_NIC : currentNICs,
|
||||
HW_LIST_TYPE_INPUT : currentInputs,
|
||||
HW_LIST_TYPE_GRAPHICS : currentGraphics,
|
||||
HW_LIST_TYPE_SOUND : currentSounds,
|
||||
HW_LIST_TYPE_CHAR : currentChars,
|
||||
HW_LIST_TYPE_HOSTDEV : currentHostdevs,
|
||||
HW_LIST_TYPE_VIDEO : currentVids,
|
||||
HW_LIST_TYPE_WATCHDOG : currentWatchdogs,
|
||||
}
|
||||
# Existing device, don't remove it
|
||||
if not olddev or olddev in currentDevices:
|
||||
continue
|
||||
|
||||
|
||||
hwtype = row[HW_LIST_COL_TYPE]
|
||||
if (mapping.has_key(hwtype) and not
|
||||
mapping[hwtype].has_key(row[HW_LIST_COL_KEY])):
|
||||
removeIt = True
|
||||
|
||||
if removeIt:
|
||||
# Re-select the first row, if we're viewing the device
|
||||
# we're about to remove
|
||||
(selModel, selIter) = hw_list.get_selection().get_selected()
|
||||
selType = selModel.get_value(selIter, HW_LIST_COL_TYPE)
|
||||
selKey = selModel.get_value(selIter, HW_LIST_COL_KEY)
|
||||
if (selType == row[HW_LIST_COL_TYPE] and
|
||||
selKey == row[HW_LIST_COL_KEY]):
|
||||
hw_list.get_selection().select_iter(
|
||||
selModel.iter_nth_child(None, 0))
|
||||
|
||||
# Now actually remove it
|
||||
hw_list_model.remove(_iter)
|
||||
hw_list_model.remove(_iter)
|
||||
|
||||
def repopulate_boot_list(self, bootdevs=None, dev_select=None):
|
||||
boot_list = self.window.get_widget("config-boot-list")
|
||||
|
@ -27,7 +27,6 @@ import virtinst
|
||||
from virtManager import util
|
||||
import virtinst.util as vutil
|
||||
import virtinst.support as support
|
||||
from virtinst import VirtualDevice
|
||||
|
||||
from virtManager.libvirtobject import vmmLibvirtObject
|
||||
|
||||
@ -135,17 +134,17 @@ class vmmDomainBase(vmmLibvirtObject):
|
||||
|
||||
def attach_device(self, devobj, devxml=None):
|
||||
raise NotImplementedError()
|
||||
def detach_device(self, devtype, dev_id_info):
|
||||
def detach_device(self, devtype, devobj):
|
||||
raise NotImplementedError()
|
||||
|
||||
def add_device(self, devobj):
|
||||
raise NotImplementedError()
|
||||
def remove_device(self, dev_type, dev_id_info):
|
||||
def remove_device(self, dev_type, devobj):
|
||||
raise NotImplementedError()
|
||||
|
||||
def define_storage_media(self, dev_id_info, newpath, _type=None):
|
||||
def define_storage_media(self, devobj, newpath, _type=None):
|
||||
raise NotImplementedError()
|
||||
def hotplug_storage_media(self, dev_id_info, newpath, _type=None):
|
||||
def hotplug_storage_media(self, devobj, newpath, _type=None):
|
||||
raise NotImplementedError()
|
||||
|
||||
def define_vcpus(self, vcpus):
|
||||
@ -175,25 +174,25 @@ class vmmDomainBase(vmmLibvirtObject):
|
||||
def define_description(self, newvalue):
|
||||
raise NotImplementedError()
|
||||
|
||||
def define_disk_readonly(self, dev_id_info, do_readonly):
|
||||
def define_disk_readonly(self, devobj, do_readonly):
|
||||
raise NotImplementedError()
|
||||
def define_disk_shareable(self, dev_id_info, do_shareable):
|
||||
def define_disk_shareable(self, devobj, do_shareable):
|
||||
raise NotImplementedError()
|
||||
def define_disk_cache(self, dev_id_info, new_cache):
|
||||
def define_disk_cache(self, devobj, new_cache):
|
||||
raise NotImplementedError()
|
||||
|
||||
def define_network_model(self, dev_id_info, newmodel):
|
||||
def define_network_model(self, devobj, newmodel):
|
||||
raise NotImplementedError()
|
||||
|
||||
def define_sound_model(self, dev_id_info, newmodel):
|
||||
def define_sound_model(self, devobj, newmodel):
|
||||
raise NotImplementedError()
|
||||
|
||||
def define_video_model(self, dev_id_info, newmodel):
|
||||
def define_video_model(self, devobj, newmodel):
|
||||
raise NotImplementedError()
|
||||
|
||||
def define_watchdog_model(self, dev_id_info, newmodel):
|
||||
def define_watchdog_model(self, devobj, newmodel):
|
||||
raise NotImplementedError()
|
||||
def define_watchdog_action(self, dev_id_info, newmodel):
|
||||
def define_watchdog_action(self, devobj, newmodel):
|
||||
raise NotImplementedError()
|
||||
|
||||
########################
|
||||
@ -364,12 +363,37 @@ class vmmDomainBase(vmmLibvirtObject):
|
||||
vncuri]
|
||||
|
||||
|
||||
def get_disk_devices(self, refresh_if_necc=True, inactive=False):
|
||||
device_type = "disk"
|
||||
def _build_device_list(self, device_type,
|
||||
refresh_if_necc=True, inactive=False):
|
||||
guest = self._get_guest(refresh_if_necc=refresh_if_necc,
|
||||
inactive=inactive)
|
||||
devs = guest.get_devices(device_type)
|
||||
|
||||
count = 0
|
||||
for dev in devs:
|
||||
dev.index = count
|
||||
count += 1
|
||||
|
||||
return devs
|
||||
|
||||
def get_network_devices(self, refresh_if_necc=True):
|
||||
return self._build_device_list("interface", refresh_if_necc)
|
||||
def get_video_devices(self):
|
||||
return self._build_device_list("video")
|
||||
def get_hostdev_devices(self):
|
||||
return self._build_device_list("hostdev")
|
||||
def get_watchdog_devices(self):
|
||||
return self._build_device_list("watchdog")
|
||||
def get_input_devices(self):
|
||||
return self._build_device_list("input")
|
||||
def get_graphics_devices(self):
|
||||
return self._build_device_list("graphics")
|
||||
def get_sound_devices(self):
|
||||
return self._build_device_list("sound")
|
||||
|
||||
def get_disk_devices(self, refresh_if_necc=True, inactive=False):
|
||||
devs = self._build_device_list("disk", refresh_if_necc, inactive)
|
||||
|
||||
# Iterate through all disks and calculate what number they are
|
||||
# HACK: We are making a variable in VirtualDisk to store the index
|
||||
idx_mapping = {}
|
||||
@ -386,55 +410,13 @@ class vmmDomainBase(vmmLibvirtObject):
|
||||
|
||||
return devs
|
||||
|
||||
def get_network_devices(self, refresh_if_necc=True):
|
||||
device_type = "interface"
|
||||
guest = self._get_guest(refresh_if_necc=refresh_if_necc)
|
||||
devs = guest.get_devices(device_type)
|
||||
return devs
|
||||
|
||||
def get_input_devices(self):
|
||||
device_type = "input"
|
||||
guest = self._get_guest()
|
||||
devs = guest.get_devices(device_type)
|
||||
|
||||
return devs
|
||||
|
||||
def get_graphics_devices(self):
|
||||
device_type = "graphics"
|
||||
guest = self._get_guest()
|
||||
devs = guest.get_devices(device_type)
|
||||
count = 0
|
||||
for dev in devs:
|
||||
dev.index = count
|
||||
count += 1
|
||||
|
||||
return devs
|
||||
|
||||
def get_sound_devices(self):
|
||||
device_type = "sound"
|
||||
guest = self._get_guest()
|
||||
devs = guest.get_devices(device_type)
|
||||
count = 0
|
||||
for dev in devs:
|
||||
dev.index = count
|
||||
count += 1
|
||||
|
||||
return devs
|
||||
|
||||
def get_char_devices(self):
|
||||
devs = []
|
||||
guest = self._get_guest()
|
||||
|
||||
serials = guest.get_devices("serial")
|
||||
parallels = guest.get_devices("parallel")
|
||||
consoles = guest.get_devices("console")
|
||||
serials = self._build_device_list("serial")
|
||||
parallels = self._build_device_list("parallel")
|
||||
consoles = self._build_device_list("console")
|
||||
|
||||
for devicelist in [serials, parallels, consoles]:
|
||||
count = 0
|
||||
for dev in devicelist:
|
||||
dev.index = count
|
||||
count += 1
|
||||
|
||||
devs.extend(devicelist)
|
||||
|
||||
# Don't display <console> if it's just a duplicate of <serial>
|
||||
@ -444,132 +426,38 @@ class vmmDomainBase(vmmLibvirtObject):
|
||||
|
||||
if (con.char_type == ser.char_type and
|
||||
con.target_type is None or con.target_type == "serial"):
|
||||
ser.console_dup = True
|
||||
ser.virtmanager_console_dup = con
|
||||
devs.remove(con)
|
||||
|
||||
return devs
|
||||
|
||||
def get_video_devices(self):
|
||||
device_type = "video"
|
||||
guest = self._get_guest()
|
||||
devs = guest.get_devices(device_type)
|
||||
count = 0
|
||||
for dev in devs:
|
||||
dev.index = count
|
||||
count += 1
|
||||
|
||||
return devs
|
||||
|
||||
def get_hostdev_devices(self):
|
||||
device_type = "hostdev"
|
||||
guest = self._get_guest()
|
||||
devs = guest.get_devices(device_type)
|
||||
count = 0
|
||||
for dev in devs:
|
||||
dev.index = count
|
||||
count += 1
|
||||
|
||||
|
||||
# [device type, unique, hwlist label, hostdev mode,
|
||||
# hostdev type, source desc label]
|
||||
#hostdevs.append(["hostdev", index, hwlabel, mode, typ,
|
||||
# srclabel, unique])
|
||||
|
||||
|
||||
return devs
|
||||
|
||||
|
||||
def get_watchdog_devices(self):
|
||||
device_type = "watchdog"
|
||||
guest = self._get_guest()
|
||||
devs = guest.get_devices(device_type)
|
||||
count = 0
|
||||
for dev in devs:
|
||||
dev.index = count
|
||||
count += 1
|
||||
|
||||
return devs
|
||||
|
||||
def _get_device_xml(self, dev_type, dev_id_info):
|
||||
def _get_device_xml(self, dev_type, devobj):
|
||||
vmxml = self.get_xml()
|
||||
|
||||
def dev_xml_serialize(doc, ctx):
|
||||
nodes = self._get_device_xml_nodes(ctx, dev_type, dev_id_info)
|
||||
nodes = self._get_device_xml_nodes(ctx, dev_type, devobj)
|
||||
if nodes:
|
||||
return nodes[0].serialize()
|
||||
|
||||
return util.xml_parse_wrapper(vmxml, dev_xml_serialize)
|
||||
|
||||
def _get_device_xml_xpath(self, dev_type, dev_id_info):
|
||||
"""
|
||||
Generate the XPath needed to lookup the passed device info
|
||||
"""
|
||||
xpath = None
|
||||
|
||||
if dev_type=="interface":
|
||||
xpath = ("/domain/devices/interface[mac/@address='%s'][1]" %
|
||||
dev_id_info)
|
||||
|
||||
elif dev_type=="disk":
|
||||
xpath = "/domain/devices/disk[target/@dev='%s'][1]" % dev_id_info
|
||||
|
||||
elif dev_type=="input":
|
||||
typ, bus = dev_id_info.split(":")
|
||||
xpath = ("/domain/devices/input[@type='%s' and @bus='%s'][1]" %
|
||||
(typ, bus))
|
||||
|
||||
elif dev_type=="graphics":
|
||||
xpath = "/domain/devices/graphics[%s]" % (int(dev_id_info) + 1)
|
||||
|
||||
elif dev_type == "sound":
|
||||
xpath = "/domain/devices/sound[%s]" % (int(dev_id_info) + 1)
|
||||
|
||||
elif (dev_type == "parallel" or
|
||||
dev_type == "console" or
|
||||
dev_type == "serial"):
|
||||
if dev_id_info.count(":"):
|
||||
ignore, dev_id_info = dev_id_info.split(":")
|
||||
xpath = ("/domain/devices/%s[target/@port='%s'][1]" %
|
||||
(dev_type, dev_id_info))
|
||||
|
||||
elif dev_type == "hostdev":
|
||||
xpath = "/domain/devices/hostdev[%s]" % (int(dev_id_info) + 1)
|
||||
|
||||
elif dev_type == "video":
|
||||
xpath = "/domain/devices/video[%s]" % (int(dev_id_info) + 1)
|
||||
|
||||
elif dev_type == "watchdog":
|
||||
xpath = "/domain/devices/watchdog[%s]" % (int(dev_id_info) + 1)
|
||||
|
||||
else:
|
||||
raise RuntimeError(_("Unknown device type '%s'") % dev_type)
|
||||
|
||||
if not xpath:
|
||||
raise RuntimeError(_("Couldn't build xpath for device %s:%s") %
|
||||
(dev_type, dev_id_info))
|
||||
|
||||
return xpath
|
||||
|
||||
def _get_device_xml_nodes(self, ctx, dev_type, dev_id_info):
|
||||
def _get_device_xml_nodes(self, ctx, dev_type, devobj):
|
||||
"""
|
||||
Return nodes needed to alter/remove the desired device
|
||||
"""
|
||||
xpath = self._get_device_xml_xpath(dev_type, dev_id_info)
|
||||
|
||||
xpath = devobj.get_xml_node_path()
|
||||
ret = ctx.xpathEval(xpath)
|
||||
|
||||
# If serial and console are both present, console is
|
||||
# probably (always?) just a dup of the 'primary' serial
|
||||
# device. Try and find an associated console device with
|
||||
# the same port and remove that as well, otherwise the
|
||||
# removal doesn't go through on libvirt <= 0.4.4
|
||||
if dev_type == "serial":
|
||||
con = ctx.xpathEval("/domain/devices/console[target/@port='%s'][1]"
|
||||
% dev_id_info)
|
||||
if con and len(con) > 0 and ret:
|
||||
ret.append(con[0])
|
||||
# HACK: If serial and console are both present, they both need
|
||||
# to be removed at the same time
|
||||
if hasattr(devobj, "virtmanager_console_dup"):
|
||||
con = getattr(devobj, "virtmanager_console_dup")
|
||||
connode = ctx.xpathEval(con.get_xml_node_path())
|
||||
connode = connode and connode[0] or None
|
||||
if connode and ret:
|
||||
ret.append(connode)
|
||||
|
||||
if not ret or len(ret) <= 0:
|
||||
if not ret:
|
||||
raise RuntimeError(_("Could not find device %s") % xpath)
|
||||
|
||||
return ret
|
||||
@ -1128,11 +1016,11 @@ class vmmDomain(vmmDomainBase):
|
||||
|
||||
self._backend.attachDevice(devxml)
|
||||
|
||||
def detach_device(self, devtype, dev_id_info):
|
||||
def detach_device(self, devtype, devobj):
|
||||
"""
|
||||
Hotunplug device from running guest
|
||||
"""
|
||||
xml = self._get_device_xml(devtype, dev_id_info)
|
||||
xml = self._get_device_xml(devtype, devobj)
|
||||
if self.is_active():
|
||||
self._backend.detachDevice(xml)
|
||||
|
||||
@ -1178,7 +1066,7 @@ class vmmDomain(vmmDomainBase):
|
||||
def _reparse_xml(self, ignore=None):
|
||||
self._guest = self._build_guest(self._get_domain_xml())
|
||||
|
||||
def _check_device_is_present(self, dev_type, dev_id_info):
|
||||
def _check_device_is_present(self, dev_type, devobj):
|
||||
"""
|
||||
Return True if device is present in the inactive XML, False otherwise.
|
||||
If device can not be found in either the active or inactive XML,
|
||||
@ -1190,12 +1078,12 @@ class vmmDomain(vmmDomainBase):
|
||||
"""
|
||||
vmxml = self.get_xml(inactive=True)
|
||||
|
||||
def find_dev(doc, ctx, dev_type, dev_id_info):
|
||||
ret = self._get_device_xml_nodes(ctx, dev_type, dev_id_info)
|
||||
def find_dev(doc, ctx, dev_type, devobj):
|
||||
ret = self._get_device_xml_nodes(ctx, dev_type, devobj)
|
||||
return ret is not None
|
||||
|
||||
try:
|
||||
util.xml_parse_wrapper(vmxml, find_dev, dev_type, dev_id_info)
|
||||
util.xml_parse_wrapper(vmxml, find_dev, dev_type, devobj)
|
||||
return True
|
||||
except Exception, e:
|
||||
# If we are removing multiple dev from an active VM, a double
|
||||
@ -1203,7 +1091,7 @@ class vmmDomain(vmmDomainBase):
|
||||
# in the active XML, assume all is good.
|
||||
try:
|
||||
util.xml_parse_wrapper(self.get_xml(), find_dev,
|
||||
dev_type, dev_id_info)
|
||||
dev_type, devobj)
|
||||
return False
|
||||
except:
|
||||
raise e
|
||||
@ -1221,18 +1109,18 @@ class vmmDomain(vmmDomainBase):
|
||||
|
||||
self._redefine(_add_xml_device, devxml)
|
||||
|
||||
def remove_device(self, dev_type, dev_id_info):
|
||||
def remove_device(self, dev_type, devobj):
|
||||
"""
|
||||
Remove device of type 'dev_type' with unique info 'dev_id_info' from
|
||||
Remove device of type 'dev_type' with unique info 'devobj' from
|
||||
the inactive guest XML
|
||||
"""
|
||||
if not self._check_device_is_present(dev_type, dev_id_info):
|
||||
if not self._check_device_is_present(dev_type, devobj):
|
||||
return
|
||||
|
||||
def _remove_xml_device(vmxml, dev_type, dev_id_info):
|
||||
def _remove_xml_device(vmxml, dev_type, devobj):
|
||||
|
||||
def unlink_dev_node(doc, ctx):
|
||||
ret = self._get_device_xml_nodes(ctx, dev_type, dev_id_info)
|
||||
ret = self._get_device_xml_nodes(ctx, dev_type, devobj)
|
||||
|
||||
for node in ret:
|
||||
node.unlinkNode()
|
||||
@ -1243,14 +1131,14 @@ class vmmDomain(vmmDomainBase):
|
||||
|
||||
return util.xml_parse_wrapper(vmxml, unlink_dev_node)
|
||||
|
||||
self._redefine(_remove_xml_device, dev_type, dev_id_info)
|
||||
self._redefine(_remove_xml_device, dev_type, devobj)
|
||||
|
||||
# Media change
|
||||
|
||||
# Helper for connecting a new source path to an existing disk
|
||||
def _media_xml_connect(self, doc, ctx, dev_id_info, newpath, _type):
|
||||
def _media_xml_connect(self, doc, ctx, devobj, newpath, _type):
|
||||
disk_fragment = self._get_device_xml_nodes(ctx, "disk",
|
||||
dev_id_info)[0]
|
||||
devobj)[0]
|
||||
driver_fragment = None
|
||||
|
||||
for child in disk_fragment.children or []:
|
||||
@ -1275,9 +1163,9 @@ class vmmDomain(vmmDomainBase):
|
||||
return doc.serialize(), disk_fragment.serialize()
|
||||
|
||||
# Helper for disconnecting a path from an existing disk
|
||||
def _media_xml_disconnect(self, doc, ctx, dev_id_info, newpath, _type):
|
||||
def _media_xml_disconnect(self, doc, ctx, devobj, newpath, _type):
|
||||
disk_fragment = self._get_device_xml_nodes(ctx, "disk",
|
||||
dev_id_info)[0]
|
||||
devobj)[0]
|
||||
sourcenode = None
|
||||
|
||||
for child in disk_fragment.children:
|
||||
@ -1293,8 +1181,8 @@ class vmmDomain(vmmDomainBase):
|
||||
|
||||
return doc.serialize(), disk_fragment.serialize()
|
||||
|
||||
def define_storage_media(self, dev_id_info, newpath, _type=None):
|
||||
if not self._check_device_is_present("disk", dev_id_info):
|
||||
def define_storage_media(self, devobj, newpath, _type=None):
|
||||
if not self._check_device_is_present("disk", devobj):
|
||||
return
|
||||
|
||||
if not newpath:
|
||||
@ -1303,19 +1191,19 @@ class vmmDomain(vmmDomainBase):
|
||||
func = self._media_xml_connect
|
||||
|
||||
def change_storage_helper(origxml):
|
||||
vmxml, ignore = util.xml_parse_wrapper(origxml, func, dev_id_info,
|
||||
vmxml, ignore = util.xml_parse_wrapper(origxml, func, devobj,
|
||||
newpath, _type)
|
||||
return vmxml
|
||||
self._redefine(change_storage_helper)
|
||||
|
||||
def hotplug_storage_media(self, dev_id_info, newpath, _type=None):
|
||||
def hotplug_storage_media(self, devobj, newpath, _type=None):
|
||||
if not newpath:
|
||||
func = self._media_xml_disconnect
|
||||
else:
|
||||
func = self._media_xml_connect
|
||||
|
||||
ignore, diskxml = util.xml_parse_wrapper(self.get_xml(), func,
|
||||
dev_id_info, newpath, _type)
|
||||
devobj, newpath, _type)
|
||||
|
||||
self.attach_device(None, diskxml)
|
||||
|
||||
@ -1531,8 +1419,8 @@ class vmmDomain(vmmDomainBase):
|
||||
|
||||
return self._redefine(util.xml_parse_wrapper, change_desc, newvalue)
|
||||
|
||||
def _change_disk_param(self, doc, ctx, dev_id_info, node_name, newvalue):
|
||||
disk_node = self._get_device_xml_nodes(ctx, "disk", dev_id_info)[0]
|
||||
def _change_disk_param(self, doc, ctx, devobj, node_name, newvalue):
|
||||
disk_node = self._get_device_xml_nodes(ctx, "disk", devobj)[0]
|
||||
|
||||
found_node = None
|
||||
for child in disk_node.children:
|
||||
@ -1551,27 +1439,27 @@ class vmmDomain(vmmDomainBase):
|
||||
return doc.serialize()
|
||||
|
||||
# Disk properties
|
||||
def define_disk_readonly(self, dev_id_info, do_readonly):
|
||||
if not self._check_device_is_present("disk", dev_id_info):
|
||||
def define_disk_readonly(self, devobj, do_readonly):
|
||||
if not self._check_device_is_present("disk", devobj):
|
||||
return
|
||||
|
||||
return self._redefine(util.xml_parse_wrapper, self._change_disk_param,
|
||||
dev_id_info, "readonly", do_readonly)
|
||||
devobj, "readonly", do_readonly)
|
||||
|
||||
def define_disk_shareable(self, dev_id_info, do_shareable):
|
||||
if not self._check_device_is_present("disk", dev_id_info):
|
||||
def define_disk_shareable(self, devobj, do_shareable):
|
||||
if not self._check_device_is_present("disk", devobj):
|
||||
return
|
||||
|
||||
return self._redefine(util.xml_parse_wrapper, self._change_disk_param,
|
||||
dev_id_info, "shareable", do_shareable)
|
||||
devobj, "shareable", do_shareable)
|
||||
|
||||
def define_disk_cache(self, dev_id_info, new_cache):
|
||||
def define_disk_cache(self, devobj, new_cache):
|
||||
devtype = "disk"
|
||||
if not self._check_device_is_present(devtype, dev_id_info):
|
||||
if not self._check_device_is_present(devtype, devobj):
|
||||
return
|
||||
|
||||
def change_cache(doc, ctx):
|
||||
dev_node = self._get_device_xml_nodes(ctx, devtype, dev_id_info)[0]
|
||||
dev_node = self._get_device_xml_nodes(ctx, devtype, devobj)[0]
|
||||
tmpnode = dev_node.xpathEval("./driver")
|
||||
node = tmpnode and tmpnode[0] or None
|
||||
|
||||
@ -1589,13 +1477,13 @@ class vmmDomain(vmmDomainBase):
|
||||
return self._redefine(util.xml_parse_wrapper, change_cache)
|
||||
|
||||
# Network properties
|
||||
def define_network_model(self, dev_id_info, newmodel):
|
||||
def define_network_model(self, devobj, newmodel):
|
||||
devtype = "interface"
|
||||
if not self._check_device_is_present(devtype, dev_id_info):
|
||||
if not self._check_device_is_present(devtype, devobj):
|
||||
return
|
||||
|
||||
def change_model(doc, ctx):
|
||||
dev_node = self._get_device_xml_nodes(ctx, devtype, dev_id_info)[0]
|
||||
dev_node = self._get_device_xml_nodes(ctx, devtype, devobj)[0]
|
||||
model_node = dev_node.xpathEval("./model")
|
||||
model_node = model_node and model_node[0] or None
|
||||
|
||||
@ -1614,13 +1502,13 @@ class vmmDomain(vmmDomainBase):
|
||||
return self._redefine(util.xml_parse_wrapper, change_model)
|
||||
|
||||
# Sound properties
|
||||
def define_sound_model(self, dev_id_info, newmodel):
|
||||
def define_sound_model(self, devobj, newmodel):
|
||||
devtype = "sound"
|
||||
if not self._check_device_is_present(devtype, dev_id_info):
|
||||
if not self._check_device_is_present(devtype, devobj):
|
||||
return
|
||||
|
||||
def change_model(doc, ctx):
|
||||
dev_node = self._get_device_xml_nodes(ctx, devtype, dev_id_info)[0]
|
||||
dev_node = self._get_device_xml_nodes(ctx, devtype, devobj)[0]
|
||||
dev_node.setProp("model", newmodel)
|
||||
|
||||
return doc.serialize()
|
||||
@ -1628,13 +1516,13 @@ class vmmDomain(vmmDomainBase):
|
||||
return self._redefine(util.xml_parse_wrapper, change_model)
|
||||
|
||||
# Video properties
|
||||
def define_video_model(self, dev_id_info, newmodel):
|
||||
if not self._check_device_is_present("video", dev_id_info):
|
||||
def define_video_model(self, devobj, newmodel):
|
||||
if not self._check_device_is_present("video", devobj):
|
||||
return
|
||||
|
||||
def change_model(doc, ctx, dev_id_info, newmodel):
|
||||
def change_model(doc, ctx, devobj, newmodel):
|
||||
vid_node = self._get_device_xml_nodes(ctx, "video",
|
||||
dev_id_info)[0]
|
||||
devobj)[0]
|
||||
|
||||
model_node = vid_node.xpathEval("./model")[0]
|
||||
model_node.setProp("type", newmodel)
|
||||
@ -1642,15 +1530,15 @@ class vmmDomain(vmmDomainBase):
|
||||
return doc.serialize()
|
||||
|
||||
return self._redefine(util.xml_parse_wrapper, change_model,
|
||||
dev_id_info, newmodel)
|
||||
devobj, newmodel)
|
||||
|
||||
def define_watchdog_model(self, dev_id_info, newval):
|
||||
def define_watchdog_model(self, devobj, newval):
|
||||
devtype = "watchdog"
|
||||
if not self._check_device_is_present(devtype, dev_id_info):
|
||||
if not self._check_device_is_present(devtype, devobj):
|
||||
return
|
||||
|
||||
def change(doc, ctx):
|
||||
dev_node = self._get_device_xml_nodes(ctx, devtype, dev_id_info)[0]
|
||||
dev_node = self._get_device_xml_nodes(ctx, devtype, devobj)[0]
|
||||
if newval:
|
||||
dev_node.setProp("model", newval)
|
||||
|
||||
@ -1658,13 +1546,13 @@ class vmmDomain(vmmDomainBase):
|
||||
|
||||
return self._redefine(util.xml_parse_wrapper, change)
|
||||
|
||||
def define_watchdog_action(self, dev_id_info, newval):
|
||||
def define_watchdog_action(self, devobj, newval):
|
||||
devtype = "watchdog"
|
||||
if not self._check_device_is_present(devtype, dev_id_info):
|
||||
if not self._check_device_is_present(devtype, devobj):
|
||||
return
|
||||
|
||||
def change(doc, ctx):
|
||||
dev_node = self._get_device_xml_nodes(ctx, devtype, dev_id_info)[0]
|
||||
dev_node = self._get_device_xml_nodes(ctx, devtype, devobj)[0]
|
||||
if newval:
|
||||
dev_node.setProp("action", newval)
|
||||
|
||||
@ -1799,6 +1687,9 @@ class vmmDomainVirtinst(vmmDomainBase):
|
||||
xml = self._backend.get_config_xml(install=False)
|
||||
return xml
|
||||
|
||||
def _get_guest(self, inactive=False, refresh_if_necc=True):
|
||||
return self._backend
|
||||
|
||||
def refresh_xml(self):
|
||||
# No caching, so no refresh needed
|
||||
return
|
||||
@ -1837,28 +1728,20 @@ class vmmDomainVirtinst(vmmDomainBase):
|
||||
|
||||
def attach_device(self, devobj, devxml=None):
|
||||
return
|
||||
def detach_device(self, devtype, dev_id_info):
|
||||
def detach_device(self, devtype, devobj):
|
||||
return
|
||||
|
||||
def add_device(self, devobj):
|
||||
def add_dev():
|
||||
self._backend.add_device(devobj)
|
||||
self._redefine(add_dev)
|
||||
def remove_device(self, dev_type, dev_id_info):
|
||||
dev = self._get_device_xml_object(dev_type, dev_id_info)
|
||||
|
||||
def remove_device(self, dev_type, devobj):
|
||||
ignore = dev_type
|
||||
def rm_dev():
|
||||
self._backend.remove_device(dev)
|
||||
self._backend.remove_device(devobj)
|
||||
self._redefine(rm_dev)
|
||||
|
||||
def define_storage_media(self, dev_id_info, newpath, _type=None):
|
||||
dev = self._get_device_xml_object(VirtualDevice.VIRTUAL_DEV_DISK,
|
||||
dev_id_info)
|
||||
|
||||
def change_path():
|
||||
dev.path = newpath
|
||||
self._redefine(change_path)
|
||||
def hotplug_storage_media(self, dev_id_info, newpath, _type=None):
|
||||
def hotplug_storage_media(self, devobj, newpath, _type=None):
|
||||
return
|
||||
|
||||
def define_vcpus(self, vcpus):
|
||||
@ -1921,63 +1804,47 @@ class vmmDomainVirtinst(vmmDomainBase):
|
||||
self._backend.description = newvalue
|
||||
self._redefine(change_desc)
|
||||
|
||||
def define_disk_readonly(self, dev_id_info, do_readonly):
|
||||
dev = self._get_device_xml_object(VirtualDevice.VIRTUAL_DEV_DISK,
|
||||
dev_id_info)
|
||||
|
||||
def define_storage_media(self, devobj, newpath, _type=None):
|
||||
def change_path():
|
||||
devobj.path = newpath
|
||||
self._redefine(change_path)
|
||||
def define_disk_readonly(self, devobj, do_readonly):
|
||||
def change_readonly():
|
||||
dev.read_only = do_readonly
|
||||
devobj.read_only = do_readonly
|
||||
self._redefine(change_readonly)
|
||||
def define_disk_shareable(self, dev_id_info, do_shareable):
|
||||
dev = self._get_device_xml_object(VirtualDevice.VIRTUAL_DEV_DISK,
|
||||
dev_id_info)
|
||||
|
||||
def define_disk_shareable(self, devobj, do_shareable):
|
||||
def change_shareable():
|
||||
dev.shareable = do_shareable
|
||||
devobj.shareable = do_shareable
|
||||
self._redefine(change_shareable)
|
||||
def define_disk_cache(self, dev_id_info, new_cache):
|
||||
dev = self._get_device_xml_object(VirtualDevice.VIRTUAL_DEV_DISK,
|
||||
dev_id_info)
|
||||
|
||||
def define_disk_cache(self, devobj, new_cache):
|
||||
def change_cache():
|
||||
dev.driver_cache = new_cache or None
|
||||
devobj.driver_cache = new_cache or None
|
||||
self._redefine(change_cache)
|
||||
|
||||
def define_network_model(self, dev_id_info, newmodel):
|
||||
dev = self._get_device_xml_object(VirtualDevice.VIRTUAL_DEV_NET,
|
||||
dev_id_info)
|
||||
def define_network_model(self, devobj, newmodel):
|
||||
def change_model():
|
||||
dev.model = newmodel
|
||||
devobj.model = newmodel
|
||||
self._redefine(change_model)
|
||||
|
||||
def define_sound_model(self, dev_id_info, newmodel):
|
||||
dev = self._get_device_xml_object(VirtualDevice.VIRTUAL_DEV_AUDIO,
|
||||
dev_id_info)
|
||||
def define_sound_model(self, devobj, newmodel):
|
||||
def change_model():
|
||||
dev.model = newmodel
|
||||
devobj.model = newmodel
|
||||
self._redefine(change_model)
|
||||
|
||||
def define_video_model(self, dev_id_info, newmodel):
|
||||
dev = self._get_device_xml_object(VirtualDevice.VIRTUAL_DEV_VIDEO,
|
||||
dev_id_info)
|
||||
|
||||
def define_video_model(self, devobj, newmodel):
|
||||
def change_video_model():
|
||||
dev.model_type = newmodel
|
||||
devobj.model_type = newmodel
|
||||
self._redefine(change_video_model)
|
||||
|
||||
def define_watchdog_model(self, dev_id_info, newval):
|
||||
devtype = VirtualDevice.VIRTUAL_DEV_WATCHDOG
|
||||
dev = self._get_device_xml_object(devtype, dev_id_info)
|
||||
def define_watchdog_model(self, devobj, newval):
|
||||
def change():
|
||||
dev.model = newval
|
||||
devobj.model = newval
|
||||
|
||||
self._redefine(change)
|
||||
|
||||
def define_watchdog_action(self, dev_id_info, newval):
|
||||
devtype = VirtualDevice.VIRTUAL_DEV_WATCHDOG
|
||||
dev = self._get_device_xml_object(devtype, dev_id_info)
|
||||
def define_watchdog_action(self, devobj, newval):
|
||||
def change():
|
||||
dev.action = newval
|
||||
devobj.action = newval
|
||||
|
||||
self._redefine(change)
|
||||
|
||||
@ -2003,72 +1870,6 @@ class vmmDomainVirtinst(vmmDomainBase):
|
||||
|
||||
self.emit("config-changed")
|
||||
|
||||
def _get_device_xml_object(self, dev_type, dev_id_info):
|
||||
"""
|
||||
Find the virtinst device for the passed id info
|
||||
"""
|
||||
def device_iter(try_func):
|
||||
devs = self._backend.get_devices(dev_type)
|
||||
for dev in devs:
|
||||
if try_func(dev):
|
||||
return dev
|
||||
|
||||
def count_func(count):
|
||||
devs = self._backend.get_devices(dev_type)
|
||||
tmpcount = -1
|
||||
for dev in devs:
|
||||
tmpcount += 1
|
||||
if count == tmpcount:
|
||||
return dev
|
||||
return None
|
||||
|
||||
found_func = None
|
||||
count = None
|
||||
|
||||
if dev_type == VirtualDevice.VIRTUAL_DEV_NET:
|
||||
found_func = (lambda x: x.macaddr == dev_id_info)
|
||||
|
||||
elif dev_type == VirtualDevice.VIRTUAL_DEV_DISK:
|
||||
found_func = (lambda x: x.target == dev_id_info)
|
||||
|
||||
elif dev_type == VirtualDevice.VIRTUAL_DEV_INPUT:
|
||||
found_func = (lambda x: (x.type == dev_id_info[0] and
|
||||
x.bus == dev_id_info[1]))
|
||||
|
||||
elif dev_type == VirtualDevice.VIRTUAL_DEV_GRAPHICS:
|
||||
count = int(dev_id_info)
|
||||
|
||||
elif dev_type == VirtualDevice.VIRTUAL_DEV_AUDIO:
|
||||
count = int(dev_id_info)
|
||||
|
||||
elif (dev_type == VirtualDevice.VIRTUAL_DEV_PARALLEL or
|
||||
dev_type == VirtualDevice.VIRTUAL_DEV_SERIAL or
|
||||
dev_type == VirtualDevice.VIRTUAL_DEV_CONSOLE):
|
||||
count = int(dev_id_info)
|
||||
|
||||
elif dev_type == VirtualDevice.VIRTUAL_DEV_HOSTDEV:
|
||||
count = int(dev_id_info)
|
||||
|
||||
elif dev_type == VirtualDevice.VIRTUAL_DEV_VIDEO:
|
||||
count = int(dev_id_info)
|
||||
|
||||
elif dev_type == VirtualDevice.VIRTUAL_DEV_WATCHDOG:
|
||||
count = int(dev_id_info)
|
||||
|
||||
else:
|
||||
raise RuntimeError(_("Unknown device type '%s'") % dev_type)
|
||||
|
||||
if count != None:
|
||||
# We are looking up devices by a simple index
|
||||
found_dev = count_func(count)
|
||||
else:
|
||||
found_dev = device_iter(found_func)
|
||||
|
||||
if not found_dev:
|
||||
raise RuntimeError(_("Did not find selected device."))
|
||||
|
||||
return found_dev
|
||||
|
||||
gobject.type_register(vmmDomainVirtinst)
|
||||
gobject.type_register(vmmDomainBase)
|
||||
gobject.type_register(vmmDomain)
|
||||
|
@ -139,6 +139,6 @@ class vmmLibvirtObject(gobject.GObject):
|
||||
self._define(newxml)
|
||||
|
||||
# Invalidate cached XML
|
||||
self._invalidate_xml()
|
||||
self.refresh_xml()
|
||||
|
||||
gobject.type_register(vmmLibvirtObject)
|
||||
|
Loading…
Reference in New Issue
Block a user