mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-01-12 09:18:00 +03:00
Add domain api for invalidating and updating cached xml.
Use this be a bit more intelligent with Details hardware list: only update list if domain xml has changed. Don't even check for new xml if the details window isn't present.
This commit is contained in:
parent
05a0c51217
commit
782406b222
@ -186,7 +186,7 @@ class vmmDetails(gobject.GObject):
|
||||
|
||||
self.addhw = None
|
||||
self.choose_cd = None
|
||||
|
||||
|
||||
self.cpu_usage_graph = sparkline.Sparkline()
|
||||
self.cpu_usage_graph.set_property("reversed", True)
|
||||
self.window.get_widget("graph-table").attach(self.cpu_usage_graph, 1, 2, 0, 1)
|
||||
@ -202,7 +202,7 @@ class vmmDetails(gobject.GObject):
|
||||
self.disk_io_graph.set_property("rgb", map(lambda x: x/255.0,
|
||||
[0x82, 0x00, 0x3B, 0x29, 0x5C, 0x45]))
|
||||
self.window.get_widget("graph-table").attach(self.disk_io_graph, 1, 2, 2, 3)
|
||||
|
||||
|
||||
self.network_traffic_graph = sparkline.Sparkline()
|
||||
self.network_traffic_graph.set_property("reversed", True)
|
||||
self.network_traffic_graph.set_property("filled", False)
|
||||
@ -331,6 +331,7 @@ class vmmDetails(gobject.GObject):
|
||||
|
||||
self.vm.connect("status-changed", self.update_widget_states)
|
||||
self.vm.connect("resources-sampled", self.refresh_resources)
|
||||
self.vm.connect("config-changed", self.refresh_vm_info)
|
||||
self.window.get_widget("hw-list").get_selection().connect("changed", self.hw_selected)
|
||||
|
||||
self.update_widget_states(self.vm, self.vm.status())
|
||||
@ -339,7 +340,7 @@ class vmmDetails(gobject.GObject):
|
||||
self.pixbuf_memory = gtk.gdk.pixbuf_new_from_file(config.get_icon_dir() + "/icon_cpu.png")
|
||||
self.prepare_hw_list()
|
||||
self.hw_selected()
|
||||
self.refresh_resources(self.vm)
|
||||
self.refresh_vm_info()
|
||||
|
||||
|
||||
# Black magic todo with scrolled windows. Basically the behaviour we want
|
||||
@ -560,8 +561,10 @@ class vmmDetails(gobject.GObject):
|
||||
return
|
||||
dialog.show_all()
|
||||
dialog.present()
|
||||
|
||||
self.engine.increment_window_counter()
|
||||
self.update_widget_states(self.vm, self.vm.status())
|
||||
self.vm.update_xml()
|
||||
|
||||
def show_help(self, src):
|
||||
# From the Details window, show the help document from the Details page
|
||||
@ -643,50 +646,47 @@ class vmmDetails(gobject.GObject):
|
||||
|
||||
|
||||
def hw_selected(self, src=None):
|
||||
vmlist = self.window.get_widget("hw-list")
|
||||
selection = vmlist.get_selection()
|
||||
active = selection.get_selected()
|
||||
if active[1] != None:
|
||||
pagetype = active[0].get_value(active[1], HW_LIST_COL_TYPE)
|
||||
pagetype = self.get_hw_selection(HW_LIST_COL_TYPE)
|
||||
if not pagetype:
|
||||
self.window.get_widget("hw-panel").set_sensitive(True)
|
||||
self.window.get_widget("hw-panel").show_all()
|
||||
|
||||
pagenum = pagetype
|
||||
if pagetype == HW_LIST_TYPE_GENERAL:
|
||||
pass
|
||||
elif pagetype == HW_LIST_TYPE_STATS:
|
||||
self.refresh_stats_page()
|
||||
elif pagetype == HW_LIST_TYPE_CPU:
|
||||
self.window.get_widget("config-vcpus-apply").set_sensitive(False)
|
||||
self.refresh_config_cpu()
|
||||
elif pagetype == HW_LIST_TYPE_MEMORY:
|
||||
self.window.get_widget("config-memory-apply").set_sensitive(False)
|
||||
self.refresh_config_memory()
|
||||
elif pagetype == HW_LIST_TYPE_BOOT:
|
||||
self.refresh_boot_page()
|
||||
self.window.get_widget("config-boot-options-apply").set_sensitive(False)
|
||||
elif pagetype == HW_LIST_TYPE_DISK:
|
||||
self.refresh_disk_page()
|
||||
elif pagetype == HW_LIST_TYPE_NIC:
|
||||
self.refresh_network_page()
|
||||
elif pagetype == HW_LIST_TYPE_INPUT:
|
||||
self.refresh_input_page()
|
||||
elif pagetype == HW_LIST_TYPE_GRAPHICS:
|
||||
self.refresh_graphics_page()
|
||||
elif pagetype == HW_LIST_TYPE_SOUND:
|
||||
self.refresh_sound_page()
|
||||
elif pagetype == HW_LIST_TYPE_CHAR:
|
||||
self.refresh_char_page()
|
||||
elif pagetype == HW_LIST_TYPE_HOSTDEV:
|
||||
self.refresh_hostdev_page()
|
||||
else:
|
||||
pagenum = -1
|
||||
|
||||
self.window.get_widget("hw-panel").set_current_page(pagenum)
|
||||
else:
|
||||
self.window.get_widget("hw-panel").set_sensitive(False)
|
||||
selection.select_path(0)
|
||||
self.window.get_widget("hw-list").get_selection().select_path(0)
|
||||
self.window.get_widget("hw-panel").set_current_page(0)
|
||||
return
|
||||
|
||||
self.window.get_widget("hw-panel").set_sensitive(True)
|
||||
self.window.get_widget("hw-panel").show_all()
|
||||
|
||||
if pagetype == HW_LIST_TYPE_GENERAL:
|
||||
pass
|
||||
elif pagetype == HW_LIST_TYPE_STATS:
|
||||
self.refresh_stats_page()
|
||||
elif pagetype == HW_LIST_TYPE_CPU:
|
||||
self.window.get_widget("config-vcpus-apply").set_sensitive(False)
|
||||
self.refresh_config_cpu()
|
||||
elif pagetype == HW_LIST_TYPE_MEMORY:
|
||||
self.window.get_widget("config-memory-apply").set_sensitive(False)
|
||||
self.refresh_config_memory()
|
||||
elif pagetype == HW_LIST_TYPE_BOOT:
|
||||
self.refresh_boot_page()
|
||||
self.window.get_widget("config-boot-options-apply").set_sensitive(False)
|
||||
elif pagetype == HW_LIST_TYPE_DISK:
|
||||
self.refresh_disk_page()
|
||||
elif pagetype == HW_LIST_TYPE_NIC:
|
||||
self.refresh_network_page()
|
||||
elif pagetype == HW_LIST_TYPE_INPUT:
|
||||
self.refresh_input_page()
|
||||
elif pagetype == HW_LIST_TYPE_GRAPHICS:
|
||||
self.refresh_graphics_page()
|
||||
elif pagetype == HW_LIST_TYPE_SOUND:
|
||||
self.refresh_sound_page()
|
||||
elif pagetype == HW_LIST_TYPE_CHAR:
|
||||
self.refresh_char_page()
|
||||
elif pagetype == HW_LIST_TYPE_HOSTDEV:
|
||||
self.refresh_hostdev_page()
|
||||
else:
|
||||
pagetype = -1
|
||||
|
||||
self.window.get_widget("hw-panel").set_current_page(pagetype)
|
||||
|
||||
def control_vm_pause(self, src):
|
||||
if self.ignorePause:
|
||||
@ -843,44 +843,58 @@ class vmmDetails(gobject.GObject):
|
||||
def switch_page(self, ignore1=None, ignore2=None, newpage=None):
|
||||
self.page_refresh(newpage)
|
||||
|
||||
def refresh_resources(self, ignore=None):
|
||||
def refresh_resources(self, ignore):
|
||||
details = self.window.get_widget("details-pages")
|
||||
page = details.get_current_page()
|
||||
|
||||
if self.is_visible():
|
||||
# Force an xml update, so we check for changed xml on every tick
|
||||
self.vm.update_xml()
|
||||
|
||||
if (page == PAGE_DETAILS and
|
||||
self.get_hw_selection(HW_LIST_COL_TYPE) == HW_LIST_TYPE_STATS):
|
||||
self.refresh_stats_page()
|
||||
|
||||
def refresh_vm_info(self, ignore=None):
|
||||
details = self.window.get_widget("details-pages")
|
||||
self.page_refresh(details.get_current_page())
|
||||
|
||||
def page_refresh(self, page):
|
||||
if page == PAGE_DETAILS:
|
||||
# Add / remove new devices
|
||||
self.repopulate_hw_list()
|
||||
if page != PAGE_DETAILS:
|
||||
return
|
||||
|
||||
# Now refresh desired page
|
||||
hw_list = self.window.get_widget("hw-list")
|
||||
selection = hw_list.get_selection()
|
||||
active = selection.get_selected()
|
||||
if active[1] != None:
|
||||
pagetype = active[0].get_value(active[1], HW_LIST_COL_TYPE)
|
||||
if pagetype == HW_LIST_TYPE_GENERAL:
|
||||
# Nothing to refresh at this point
|
||||
pass
|
||||
elif pagetype == HW_LIST_TYPE_STATS:
|
||||
self.refresh_stats_page()
|
||||
elif pagetype == HW_LIST_TYPE_CPU:
|
||||
self.refresh_config_cpu()
|
||||
elif pagetype == HW_LIST_TYPE_MEMORY:
|
||||
self.refresh_config_memory()
|
||||
elif pagetype == HW_LIST_TYPE_DISK:
|
||||
self.refresh_disk_page()
|
||||
elif pagetype == HW_LIST_TYPE_NIC:
|
||||
self.refresh_network_page()
|
||||
elif pagetype == HW_LIST_TYPE_INPUT:
|
||||
self.refresh_input_page()
|
||||
elif pagetype == HW_LIST_TYPE_GRAPHICS:
|
||||
self.refresh_graphics_page()
|
||||
elif pagetype == HW_LIST_TYPE_SOUND:
|
||||
self.refresh_sound_page()
|
||||
elif pagetype == HW_LIST_TYPE_CHAR:
|
||||
self.refresh_char_page()
|
||||
elif pagetype == HW_LIST_TYPE_HOSTDEV:
|
||||
self.refresh_hostdev_page()
|
||||
# This function should only be called when the VM xml actually
|
||||
# changes (not everytime it is refreshed). This saves us from blindly
|
||||
# parsing the xml every tick
|
||||
|
||||
pagetype = self.get_hw_selection(HW_LIST_COL_TYPE)
|
||||
|
||||
# Add / remove new devices
|
||||
self.repopulate_hw_list()
|
||||
|
||||
if pagetype == HW_LIST_TYPE_GENERAL:
|
||||
# Nothing to refresh at this point
|
||||
pass
|
||||
elif pagetype == HW_LIST_TYPE_STATS:
|
||||
self.refresh_stats_page()
|
||||
elif pagetype == HW_LIST_TYPE_CPU:
|
||||
self.refresh_config_cpu()
|
||||
elif pagetype == HW_LIST_TYPE_MEMORY:
|
||||
self.refresh_config_memory()
|
||||
elif pagetype == HW_LIST_TYPE_DISK:
|
||||
self.refresh_disk_page()
|
||||
elif pagetype == HW_LIST_TYPE_NIC:
|
||||
self.refresh_network_page()
|
||||
elif pagetype == HW_LIST_TYPE_INPUT:
|
||||
self.refresh_input_page()
|
||||
elif pagetype == HW_LIST_TYPE_GRAPHICS:
|
||||
self.refresh_graphics_page()
|
||||
elif pagetype == HW_LIST_TYPE_SOUND:
|
||||
self.refresh_sound_page()
|
||||
elif pagetype == HW_LIST_TYPE_CHAR:
|
||||
self.refresh_char_page()
|
||||
elif pagetype == HW_LIST_TYPE_HOSTDEV:
|
||||
self.refresh_hostdev_page()
|
||||
|
||||
def refresh_stats_page(self):
|
||||
def _rx_tx_text(rx, tx, unit):
|
||||
@ -987,7 +1001,7 @@ class vmmDetails(gobject.GObject):
|
||||
else:
|
||||
perms = "Read/Write"
|
||||
if diskinfo[7] == True:
|
||||
perms += ", Sharable"
|
||||
perms += ", Shareable"
|
||||
self.window.get_widget("disk-permissions").set_text(perms)
|
||||
bus = diskinfo[8] or _("Unknown")
|
||||
self.window.get_widget("disk-bus").set_text(bus)
|
||||
@ -1531,7 +1545,7 @@ class vmmDetails(gobject.GObject):
|
||||
return
|
||||
|
||||
self.remove_device(info[0], info[1])
|
||||
self.refresh_resources()
|
||||
self.vm.update_xml()
|
||||
|
||||
def prepare_hw_list(self):
|
||||
hw_list_model = gtk.ListStore(str, str, int, gtk.gdk.Pixbuf, int, gobject.TYPE_PYOBJECT)
|
||||
@ -1770,7 +1784,7 @@ class vmmDetails(gobject.GObject):
|
||||
self.addhw.show()
|
||||
|
||||
def add_hardware_done(self, ignore=None):
|
||||
self.refresh_resources()
|
||||
self.vm.update_xml()
|
||||
|
||||
def toggle_cdrom(self, src):
|
||||
info = self.get_hw_selection(HW_LIST_COL_DEVICE)
|
||||
|
@ -33,6 +33,9 @@ class vmmDomain(gobject.GObject):
|
||||
"resources-sampled": (gobject.SIGNAL_RUN_FIRST,
|
||||
gobject.TYPE_NONE,
|
||||
[]),
|
||||
"config-changed": (gobject.SIGNAL_RUN_FIRST,
|
||||
gobject.TYPE_NONE,
|
||||
[]),
|
||||
}
|
||||
|
||||
def __init__(self, config, connection, vm, uuid):
|
||||
@ -49,14 +52,16 @@ class vmmDomain(gobject.GObject):
|
||||
"netRxRate" : 10.0,
|
||||
}
|
||||
|
||||
self._update_status()
|
||||
self.xml = None
|
||||
self._xml = None
|
||||
self._valid_xml = False
|
||||
|
||||
self._mem_stats = None
|
||||
self._cpu_stats = None
|
||||
self._network_traffic = None
|
||||
self._disk_io = None
|
||||
|
||||
self._update_status()
|
||||
|
||||
self.config.on_stats_enable_mem_poll_changed(self.toggle_sample_mem_stats)
|
||||
self.config.on_stats_enable_cpu_poll_changed(self.toggle_sample_cpu_stats)
|
||||
self.config.on_stats_enable_net_poll_changed(self.toggle_sample_network_traffic)
|
||||
@ -67,14 +72,26 @@ class vmmDomain(gobject.GObject):
|
||||
self.toggle_sample_network_traffic()
|
||||
self.toggle_sample_disk_io()
|
||||
|
||||
|
||||
def get_xml(self):
|
||||
if self.xml is None:
|
||||
# Get domain xml. If cached xml is invalid, update.
|
||||
if self._xml is None or not self._valid_xml:
|
||||
self.update_xml()
|
||||
return self.xml
|
||||
return self._xml
|
||||
|
||||
def update_xml(self):
|
||||
self.xml = self.vm.XMLDesc(libvirt.VIR_DOMAIN_XML_SECURE)
|
||||
# Force an xml update. Signal 'config-changed' if domain xml has
|
||||
# changed since last refresh
|
||||
|
||||
origxml = self._xml
|
||||
self._xml = self.vm.XMLDesc(libvirt.VIR_DOMAIN_XML_SECURE)
|
||||
self._valid_xml = True
|
||||
|
||||
if origxml != self._xml:
|
||||
self.emit("config-changed")
|
||||
|
||||
def invalidate_xml(self):
|
||||
# Mark cached xml as invalid
|
||||
self._valid_xml = False
|
||||
|
||||
def release_handle(self):
|
||||
del(self.vm)
|
||||
@ -121,6 +138,7 @@ class vmmDomain(gobject.GObject):
|
||||
|
||||
def is_hvm(self):
|
||||
os_type = util.get_xml_path(self.get_xml(), "/domain/os/type")
|
||||
# FIXME: This should be static, not parse xml everytime
|
||||
# XXX libvirt bug - doesn't work for inactive guests
|
||||
#os_type = self.vm.OSType()
|
||||
logging.debug("OS Type: %s" % os_type)
|
||||
@ -129,6 +147,7 @@ class vmmDomain(gobject.GObject):
|
||||
return False
|
||||
|
||||
def get_type(self):
|
||||
# FIXME: This should be static, not parse xml everytime
|
||||
return util.get_xml_path(self.get_xml(), "/domain/@type")
|
||||
|
||||
def is_vcpu_hotplug_capable(self):
|
||||
@ -261,8 +280,9 @@ class vmmDomain(gobject.GObject):
|
||||
if self.connection.get_state() != self.connection.STATE_ACTIVE:
|
||||
return
|
||||
|
||||
# Clear cached XML
|
||||
self.xml = None
|
||||
# Invalidate cached xml
|
||||
self.invalidate_xml()
|
||||
|
||||
info = self.vm.info()
|
||||
expected = self.config.get_stats_history_length()
|
||||
current = len(self.record)
|
||||
@ -588,7 +608,8 @@ class vmmDomain(gobject.GObject):
|
||||
return self._parse_device_xml(_parse_serial_consoles)
|
||||
|
||||
def get_graphics_console(self):
|
||||
self.xml = None
|
||||
self.update_xml()
|
||||
|
||||
typ = util.get_xml_path(self.get_xml(),
|
||||
"/domain/devices/graphics/@type")
|
||||
port = None
|
||||
@ -1085,7 +1106,7 @@ class vmmDomain(gobject.GObject):
|
||||
self.get_connection().define_domain(newxml)
|
||||
|
||||
# Invalidate cached XML
|
||||
self.xml = None
|
||||
self.invalidate_xml()
|
||||
|
||||
def remove_device(self, dev_type, dev_id_info):
|
||||
newxml = self._remove_xml_device(dev_type, dev_id_info)
|
||||
@ -1094,7 +1115,7 @@ class vmmDomain(gobject.GObject):
|
||||
self.get_connection().define_domain(newxml)
|
||||
|
||||
# Invalidate cached XML
|
||||
self.xml = None
|
||||
self.invalidate_xml()
|
||||
|
||||
def _change_cdrom(self, newdev, dev_id_info):
|
||||
# If vm is shutoff, remove device, and redefine with media
|
||||
@ -1234,7 +1255,7 @@ class vmmDomain(gobject.GObject):
|
||||
doc.freeDoc()
|
||||
|
||||
# Invalidate cached xml
|
||||
self.xml = None
|
||||
self.invalidate_xml()
|
||||
|
||||
def toggle_sample_cpu_stats(self, ignore1=None, ignore2=None,
|
||||
ignore3=None, ignore4=None):
|
||||
|
Loading…
Reference in New Issue
Block a user