diff --git a/src/virt-manager.schemas.in b/src/virt-manager.schemas.in index baedfc86c..92184d316 100644 --- a/src/virt-manager.schemas.in +++ b/src/virt-manager.schemas.in @@ -26,19 +26,6 @@ - - /schemas/apps/::PACKAGE::/vmlist-fields/cpu_usage - /apps/::PACKAGE::/vmlist-fields/cpu_usage - ::PACKAGE:: - bool - 1 - - - Show cpu usage in summary - Show the cpu usage field in the domain list summary view - - - /schemas/apps/::PACKAGE::/vmlist-fields/virtual_cpus /apps/::PACKAGE::/vmlist-fields/virtual_cpus @@ -66,28 +53,15 @@ - /schemas/apps/::PACKAGE::/vmlist-fields/disk_usage - /apps/::PACKAGE::/vmlist-fields/disk_usage + /schemas/apps/::PACKAGE::/vmlist-fields/stats-type + /apps/::PACKAGE::/vmlist-fields/stats-type ::PACKAGE:: - bool + int 0 - Show disk I/O in summary - Show the disk I/O field in the domain list summary view - - - - - /schemas/apps/::PACKAGE::/vmlist-fields/network_traffic - /apps/::PACKAGE::/vmlist-fields/network_traffic - ::PACKAGE:: - bool - 0 - - - Show network I/O in summary - Show the network I/O field in the domain list summary view + Stats type in manager view + Type of stats to graph (cpu, disk, net) in manager view diff --git a/src/virtManager/config.py b/src/virtManager/config.py index 41c506e86..4d3b2961c 100644 --- a/src/virtManager/config.py +++ b/src/virtManager/config.py @@ -37,6 +37,10 @@ CONSOLE_KEYGRAB_NEVER = 0 CONSOLE_KEYGRAB_FULLSCREEN = 1 CONSOLE_KEYGRAB_MOUSEOVER = 2 +STATS_CPU = 0 +STATS_DISK = 1 +STATS_NETWORK = 2 + DEFAULT_XEN_IMAGE_DIR = "/var/lib/xen/images" DEFAULT_XEN_SAVE_DIR = "/var/lib/xen/dump" @@ -235,21 +239,14 @@ class vmmConfig: def is_vmlist_status_visible(self): return self.conf.get_bool(self.conf_dir + "/vmlist-fields/status") - def is_vmlist_cpu_usage_visible(self): - return self.conf.get_bool(self.conf_dir + "/vmlist-fields/cpu_usage") - def is_vmlist_virtual_cpus_visible(self): return self.conf.get_bool(self.conf_dir + "/vmlist-fields/virtual_cpus") def is_vmlist_memory_usage_visible(self): return self.conf.get_bool(self.conf_dir + "/vmlist-fields/memory_usage") - def is_vmlist_disk_io_visible(self): - return self.conf.get_bool(self.conf_dir + "/vmlist-fields/disk_usage") - - def is_vmlist_network_traffic_visible(self): - return self.conf.get_bool(self.conf_dir + "/vmlist-fields/network_traffic") - + def get_vmlist_stats_type(self): + return self.conf.get_int(self.conf_dir + "/vmlist-fields/stats_type") def set_vmlist_domain_id_visible(self, state): @@ -258,20 +255,14 @@ class vmmConfig: def set_vmlist_status_visible(self, state): self.conf.set_bool(self.conf_dir + "/vmlist-fields/status", state) - def set_vmlist_cpu_usage_visible(self, state): - self.conf.set_bool(self.conf_dir + "/vmlist-fields/cpu_usage", state) - def set_vmlist_virtual_cpus_visible(self, state): self.conf.set_bool(self.conf_dir + "/vmlist-fields/virtual_cpus", state) def set_vmlist_memory_usage_visible(self, state): self.conf.set_bool(self.conf_dir + "/vmlist-fields/memory_usage", state) - def set_vmlist_disk_io_visible(self, state): - self.conf.set_bool(self.conf_dir + "/vmlist-fields/disk_usage", state) - - def set_vmlist_network_traffic_visible(self, state): - self.conf.set_bool(self.conf_dir + "/vmlist-fields/network_traffic", state) + def set_vmlist_stats_type(self, val): + self.conf.set_int(self.conf_dir + "/vmlist-fields/stats_type", val) def get_default_directory(self, conn, _type): @@ -311,22 +302,15 @@ class vmmConfig: def on_vmlist_status_visible_changed(self, callback): self.conf.notify_add(self.conf_dir + "/vmlist-fields/status", callback) - def on_vmlist_cpu_usage_visible_changed(self, callback): - self.conf.notify_add(self.conf_dir + "/vmlist-fields/cpu_usage", callback) - def on_vmlist_virtual_cpus_visible_changed(self, callback): self.conf.notify_add(self.conf_dir + "/vmlist-fields/virtual_cpus", callback) def on_vmlist_memory_usage_visible_changed(self, callback): self.conf.notify_add(self.conf_dir + "/vmlist-fields/memory_usage", callback) - def on_vmlist_disk_io_visible_changed(self, callback): - self.conf.notify_add(self.conf_dir + "/vmlist-fields/disk_usage", callback) - - def on_vmlist_network_traffic_visible_changed(self, callback): - self.conf.notify_add(self.conf_dir + "/vmlist-fields/network_traffic", callback) - - + def on_vmlist_stats_type_changed(self, callback): + self.conf.notify_add(self.conf_dir + "/vmlist-fields/stats_type", + callback) def get_stats_update_interval(self): interval = self.conf.get_int(self.conf_dir + "/stats/update-interval") diff --git a/src/virtManager/manager.py b/src/virtManager/manager.py index 657d76692..d8e5fd854 100644 --- a/src/virtManager/manager.py +++ b/src/virtManager/manager.py @@ -26,6 +26,7 @@ import traceback import libvirt +import virtManager.config as cfg from virtManager.connection import vmmConnection from virtManager.asyncjob import vmmAsyncJob from virtManager.error import vmmErrorDialog @@ -35,7 +36,7 @@ from virtManager import util as util VMLIST_SORT_ID = 1 VMLIST_SORT_NAME = 2 -VMLIST_SORT_CPU_USAGE = 3 +VMLIST_SORT_STATS = 3 VMLIST_SORT_MEMORY_USAGE = 4 VMLIST_SORT_DISK_IO = 5 VMLIST_SORT_NETWORK_USAGE = 6 @@ -166,30 +167,28 @@ class vmmManager(gobject.GObject): self.startup_error = None self.ignore_pause = False + self.stats_column = None + self.stats_sparkline = None + self.prepare_vmlist() self.config.on_vmlist_domain_id_visible_changed(self.toggle_domain_id_visible_widget) self.config.on_vmlist_status_visible_changed(self.toggle_status_visible_widget) - self.config.on_vmlist_cpu_usage_visible_changed(self.toggle_cpu_usage_visible_widget) self.config.on_vmlist_virtual_cpus_visible_changed(self.toggle_virtual_cpus_visible_widget) self.config.on_vmlist_memory_usage_visible_changed(self.toggle_memory_usage_visible_widget) - self.config.on_vmlist_disk_io_visible_changed(self.toggle_disk_io_visible_widget) - self.config.on_vmlist_network_traffic_visible_changed(self.toggle_network_traffic_visible_widget) + self.config.on_vmlist_stats_type_changed(self.stats_toggled_config) self.window.get_widget("menu_view_domain_id").set_active(self.config.is_vmlist_domain_id_visible()) self.window.get_widget("menu_view_status").set_active(self.config.is_vmlist_status_visible()) - self.window.get_widget("menu_view_cpu_usage").set_active(self.config.is_vmlist_cpu_usage_visible()) self.window.get_widget("menu_view_virtual_cpus").set_active(self.config.is_vmlist_virtual_cpus_visible()) self.window.get_widget("menu_view_memory_usage").set_active(self.config.is_vmlist_memory_usage_visible()) - self.window.get_widget("menu_view_disk_io").set_active(self.config.is_vmlist_disk_io_visible()) - self.window.get_widget("menu_view_network_traffic").set_active(self.config.is_vmlist_network_traffic_visible()) # Register callbacks with the global stats enable/disable values # that disable the associated vmlist widgets if reporting is disabled self.config.on_stats_enable_disk_poll_changed(self.enable_polling, - VMLIST_SORT_DISK_IO) + cfg.STATS_DISK) self.config.on_stats_enable_net_poll_changed(self.enable_polling, - VMLIST_SORT_NETWORK_USAGE) + cfg.STATS_NETWORK) self.vmmenu_icons = {} self.vmmenu_icons["run"] = gtk.Image() @@ -338,11 +337,15 @@ class vmmManager(gobject.GObject): self.window.signal_autoconnect({ "on_menu_view_domain_id_activate" : self.toggle_domain_id_visible_conf, "on_menu_view_status_activate" : self.toggle_status_visible_conf, - "on_menu_view_cpu_usage_activate" : self.toggle_cpu_usage_visible_conf, "on_menu_view_virtual_cpus_activate" : self.toggle_virtual_cpus_visible_conf, "on_menu_view_memory_usage_activate" : self.toggle_memory_usage_visible_conf, - "on_menu_view_disk_io_activate" : self.toggle_disk_io_visible_conf, - "on_menu_view_network_traffic_activate" : self.toggle_network_traffic_visible_conf, + + "on_menu_view_stats_disk_toggled" : (self.stats_toggled, + cfg.STATS_DISK), + "on_menu_view_stats_network_toggled" : (self.stats_toggled, + cfg.STATS_NETWORK), + "on_menu_view_stats_cpu_toggled" : (self.stats_toggled, + cfg.STATS_CPU), "on_vm_manager_delete_event": self.close, "on_menu_file_add_connection_activate": self.new_connection, @@ -375,9 +378,9 @@ class vmmManager(gobject.GObject): # Initialize stat polling columns based on global polling # preferences (we want signal handlers for this) for typ, init_val in \ - [ (VMLIST_SORT_DISK_IO, + [ (cfg.STATS_DISK, self.config.get_stats_enable_disk_poll()), - (VMLIST_SORT_NETWORK_USAGE, + (cfg.STATS_NETWORK, self.config.get_stats_enable_net_poll())]: self.enable_polling(None, None, init_val, typ) @@ -827,9 +830,6 @@ class vmmManager(gobject.GObject): cpuUsageCol = gtk.TreeViewColumn(_("CPU usage")) virtualCPUsCol = gtk.TreeViewColumn(_("CPUs")) memoryUsageCol = gtk.TreeViewColumn(_("Memory usage")) - # FIXME: add KBytes/s tooltip - diskIOCol = gtk.TreeViewColumn(_("Disk I/O")) - networkTrafficCol = gtk.TreeViewColumn(_("Network I/O")) vmlist.append_column(nameCol) vmlist.append_column(idCol) @@ -837,8 +837,6 @@ class vmmManager(gobject.GObject): vmlist.append_column(cpuUsageCol) vmlist.append_column(virtualCPUsCol) vmlist.append_column(memoryUsageCol) - vmlist.append_column(diskIOCol) - vmlist.append_column(networkTrafficCol) # For the columns which follow, we deliberately bind columns # to fields in the list store & on each update copy the info @@ -871,9 +869,10 @@ class vmmManager(gobject.GObject): cpuUsage_img = CellRendererSparkline() cpuUsage_img.set_property("reversed", True) cpuUsageCol.pack_start(cpuUsage_img, True) - cpuUsageCol.set_cell_data_func(cpuUsage_img, self.cpu_usage_img, None) - cpuUsageCol.set_visible(self.config.is_vmlist_cpu_usage_visible()) - cpuUsageCol.set_sort_column_id(VMLIST_SORT_CPU_USAGE) + cpuUsageCol.set_sort_column_id(VMLIST_SORT_STATS) + self.stats_sparkline = cpuUsage_img + self.stats_column = cpuUsageCol + self.stats_toggled(None, self.get_stats_type()) virtualCPUs_txt = gtk.CellRendererText() virtualCPUsCol.pack_start(virtualCPUs_txt, False) @@ -889,27 +888,10 @@ class vmmManager(gobject.GObject): memoryUsageCol.set_visible(self.config.is_vmlist_memory_usage_visible()) memoryUsageCol.set_sort_column_id(VMLIST_SORT_MEMORY_USAGE) - diskIO_img = CellRendererSparkline() - diskIO_img.set_property("reversed", True) - diskIOCol.pack_start(diskIO_img, True) - diskIOCol.set_cell_data_func(diskIO_img, self.disk_io_img, None) - diskIOCol.set_visible(self.config.is_vmlist_disk_io_visible()) - diskIOCol.set_sort_column_id(VMLIST_SORT_DISK_IO) - - networkTraffic_img = CellRendererSparkline() - networkTraffic_img.set_property("reversed", True) - networkTrafficCol.pack_start(networkTraffic_img, True) - networkTrafficCol.set_cell_data_func(networkTraffic_img, - self.network_traffic_img, None) - networkTrafficCol.set_visible(self.config.is_vmlist_network_traffic_visible()) - networkTrafficCol.set_sort_column_id(VMLIST_SORT_NETWORK_USAGE) - model.set_sort_func(VMLIST_SORT_ID, self.vmlist_domain_id_sorter) model.set_sort_func(VMLIST_SORT_NAME, self.vmlist_name_sorter) - model.set_sort_func(VMLIST_SORT_CPU_USAGE, self.vmlist_cpu_usage_sorter) - model.set_sort_func(VMLIST_SORT_MEMORY_USAGE, self.vmlist_memory_usage_sorter) - model.set_sort_func(VMLIST_SORT_DISK_IO, self.vmlist_disk_io_sorter) - model.set_sort_func(VMLIST_SORT_NETWORK_USAGE, self.vmlist_network_usage_sorter) + model.set_sort_func(VMLIST_SORT_MEMORY_USAGE, + self.vmlist_memory_usage_sorter) model.set_sort_column_id(VMLIST_SORT_NAME, gtk.SORT_ASCENDING) @@ -948,19 +930,11 @@ class vmmManager(gobject.GObject): col = vmlist.get_column(COL_STATUS) col.set_visible(self.config.is_vmlist_status_visible()) - def toggle_cpu_usage_visible_conf(self, menu): - self.config.set_vmlist_cpu_usage_visible(menu.get_active()) - - def toggle_cpu_usage_visible_widget(self, ignore1, ignore2, ignore3, ignore4): - vmlist = self.window.get_widget("vm-list") - col = vmlist.get_column(COL_CPU) - col.set_visible(self.config.is_vmlist_cpu_usage_visible()) - def enable_polling(self, ignore1, ignore2, conf_entry, userdata): - if userdata == VMLIST_SORT_DISK_IO: - widgn = "menu_view_disk_io" - elif userdata == VMLIST_SORT_NETWORK_USAGE: - widgn = "menu_view_network_traffic" + if userdata == cfg.STATS_DISK: + widgn = "menu_view_stats_disk" + elif userdata == cfg.STATS_NETWORK: + widgn = "menu_view_stats_network" widget = self.window.get_widget(widgn) tool_text = "" @@ -973,8 +947,15 @@ class vmmManager(gobject.GObject): widget.set_sensitive(False) tool_text = _("Disabled in preferences dialog.") + if self.get_stats_type() == userdata: + # Switch graphs over to guaranteed safe value + self.stats_toggled(None, cfg.STATS_CPU) + util.tooltip_wrapper(widget, tool_text) + def stats_toggled_config(self, ignore1, ignore2, conf_entry, ignore4): + self.stats_toggled(None, conf_entry.get_value().get_int()) + def toggle_virtual_cpus_visible_conf(self, menu): self.config.set_vmlist_virtual_cpus_visible(menu.get_active()) @@ -991,21 +972,44 @@ class vmmManager(gobject.GObject): col = vmlist.get_column(COL_MEM) col.set_visible(self.config.is_vmlist_memory_usage_visible()) - def toggle_disk_io_visible_conf(self, menu): - self.config.set_vmlist_disk_io_visible(menu.get_active()) + def get_stats_type(self): + return self.config.get_vmlist_stats_type() - def toggle_disk_io_visible_widget(self, ignore1, ignore2, ignore3, ignore4): - vmlist = self.window.get_widget("vm-list") - col = vmlist.get_column(COL_DISK) - col.set_visible(self.config.is_vmlist_disk_io_visible()) + def stats_toggled(self, src, stats_id): + if src and not src.get_active(): + return - def toggle_network_traffic_visible_conf(self, menu): - self.config.set_vmlist_network_traffic_visible(menu.get_active()) + if stats_id == cfg.STATS_NETWORK: + column_name = _("Network I/O") + stats_func = self.network_traffic_img + sort_func = self.vmlist_network_usage_sorter + widg = "menu_view_stats_network" + elif stats_id == cfg.STATS_DISK: + column_name = _("Disk I/O") + stats_func = self.disk_io_img + sort_func = self.vmlist_disk_io_sorter + widg = "menu_view_stats_disk" + elif stats_id == cfg.STATS_CPU: + column_name = _("CPU Usage") + stats_func = self.cpu_usage_img + sort_func = self.vmlist_cpu_usage_sorter + widg = "menu_view_stats_cpu" + else: + return - def toggle_network_traffic_visible_widget(self, ignore1, ignore2, ignore3, ignore4): - vmlist = self.window.get_widget("vm-list") - col = vmlist.get_column(COL_NETWORK) - col.set_visible(self.config.is_vmlist_network_traffic_visible()) + if not src: + self.window.get_widget(widg).set_active(True) + + if self.stats_column: + vmlist = self.window.get_widget("vm-list") + model = vmlist.get_model() + self.stats_column.set_title(column_name) + self.stats_column.set_cell_data_func(self.stats_sparkline, + stats_func, None) + model.set_sort_func(VMLIST_SORT_STATS, sort_func) + + if stats_id != self.get_stats_type(): + self.config.set_vmlist_stats_type(stats_id) def cpu_usage_img(self, column, cell, model, _iter, data): if model.get_value(_iter, ROW_HANDLE) is None: diff --git a/src/vmm-manager.glade b/src/vmm-manager.glade index 6ab98dadd..9282731b2 100644 --- a/src/vmm-manager.glade +++ b/src/vmm-manager.glade @@ -155,6 +155,47 @@ True + + + True + Stats + True + + + True + + + True + CPU + True + True + + + + + + True + Disk + True + True + menu_view_stats_cpu + + + + + + True + Network + True + True + menu_view_stats_cpu + + + + + + + True @@ -182,15 +223,6 @@ - - - True - CPU Usage - True - True - - - True @@ -200,24 +232,6 @@ - - - True - Disk I/O - True - True - - - - - - True - Network I/O - True - True - - -