Split gnome-virt-manager.py into separate modules, one per class
This commit is contained in:
parent
56f6c98966
commit
9617d52a8d
|
@ -3,5 +3,6 @@ AM_INIT_AUTOMAKE(gnome-virt-manager, 0.0.2)
|
|||
|
||||
AC_OUTPUT(Makefile
|
||||
src/Makefile
|
||||
src/virtManager/Makefile
|
||||
pixmaps/Makefile
|
||||
gnome-virt-manager.spec)
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
|
||||
SUBDIRS = virtManager
|
||||
|
||||
bin_SOURCES = gnome-virt-manager.in
|
||||
bin_SCRIPTS = gnome-virt-manager
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,21 @@
|
|||
|
||||
import gtk.glade
|
||||
|
||||
class vmmAbout:
|
||||
def __init__(self, config):
|
||||
self.window = gtk.glade.XML(config.get_glade_file(), "vmm-about")
|
||||
self.window.get_widget("vmm-about").hide()
|
||||
|
||||
self.window.signal_autoconnect({
|
||||
"on_vmm_about_delete_event": self.close,
|
||||
})
|
||||
|
||||
def show(self):
|
||||
dialog = self.window.get_widget("vmm-about")
|
||||
dialog.set_version("0.1")
|
||||
dialog.show_all()
|
||||
dialog.present()
|
||||
|
||||
def close(self,ignore1=None,ignore2=None):
|
||||
self.window.get_widget("vmm-about").hide()
|
||||
return 1
|
|
@ -0,0 +1,103 @@
|
|||
import gconf
|
||||
|
||||
class vmmConfig:
|
||||
def __init__(self, appname, gconf_dir, glade_dir, icon_dir):
|
||||
self.appname = appname
|
||||
self.conf_dir = gconf_dir
|
||||
self.conf = gconf.client_get_default()
|
||||
self.conf.add_dir (gconf_dir,
|
||||
gconf.CLIENT_PRELOAD_NONE)
|
||||
|
||||
self.glade_dir = glade_dir
|
||||
self.icon_dir = icon_dir
|
||||
|
||||
def get_appname(self):
|
||||
return self.appname
|
||||
|
||||
def get_glade_dir(self):
|
||||
return self.glade_dir
|
||||
|
||||
def get_glade_file(self):
|
||||
return self.glade_dir + "/" + self.appname + ".glade"
|
||||
|
||||
def get_icon_dir(self):
|
||||
return self.icon_dir
|
||||
|
||||
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_memory_usage_visible(self):
|
||||
return self.conf.get_bool(self.conf_dir + "/vmlist-fields/memory_usage")
|
||||
|
||||
def is_vmlist_disk_usage_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 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_memory_usage_visible(self, state):
|
||||
self.conf.set_bool(self.conf_dir + "/vmlist-fields/memory_usage", state)
|
||||
|
||||
def set_vmlist_disk_usage_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 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_memory_usage_visible_changed(self, callback):
|
||||
self.conf.notify_add(self.conf_dir + "/vmlist-fields/memory_usage", callback)
|
||||
|
||||
def on_vmlist_disk_usage_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 get_stats_update_interval(self):
|
||||
interval = self.conf.get_int(self.conf_dir + "/stats/update-interval")
|
||||
if interval < 1:
|
||||
return 1
|
||||
return interval
|
||||
|
||||
def get_stats_history_length(self):
|
||||
history = self.conf.get_int(self.conf_dir + "/stats/history-length")
|
||||
if history < 10:
|
||||
return 10
|
||||
return history
|
||||
|
||||
|
||||
def set_stats_update_interval(self, interval):
|
||||
self.conf.set_int(self.conf_dir + "/stats/update-interval", interval)
|
||||
|
||||
def set_stats_history_length(self, length):
|
||||
self.conf.set_int(self.conf_dir + "/stats/history-length", length)
|
||||
|
||||
|
||||
def on_stats_update_interval_changed(self, callback):
|
||||
self.conf.notify_add(self.conf_dir + "/stats/update-interval", callback)
|
||||
|
||||
def on_stats_history_length_changed(self, callback):
|
||||
self.conf.notify_add(self.conf_dir + "/stats/history-length", callback)
|
||||
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
|
||||
class vmmConnect:
|
||||
def __init__(self, config, engine):
|
||||
self.window = gtk.glade.XML(config.get_glade_file(), "vmm-open-connection")
|
||||
self.engine = engine
|
||||
self.window.get_widget("vmm-open-connection").hide()
|
||||
|
||||
self.window.get_widget("remote-xen-options").set_sensitive(False)
|
||||
self.window.get_widget("other-hv-options").set_sensitive(False)
|
||||
|
||||
self.window.signal_autoconnect({
|
||||
"on_type_local_xen_toggled": self.change_active_type,
|
||||
"on_type_remote_xen_toggled": self.change_active_type,
|
||||
"on_type_other_hv_toggled": self.change_active_type,
|
||||
"on_cancel_clicked": self.close,
|
||||
"on_connect_clicked": self.open_connection,
|
||||
"on_vmm_open_connection_delete_event": self.close,
|
||||
})
|
||||
|
||||
def close(self,ignore1=None,ignore2=None):
|
||||
self.window.get_widget("vmm-open-connection").hide()
|
||||
return 1
|
||||
|
||||
def show(self):
|
||||
win = self.window.get_widget("vmm-open-connection")
|
||||
win.show_all()
|
||||
win.present()
|
||||
|
||||
def change_active_type(self, src):
|
||||
if src.get_active():
|
||||
if src.get_name() == "type-local-xen":
|
||||
self.window.get_widget("remote-xen-options").set_sensitive(False)
|
||||
self.window.get_widget("other-hv-options").set_sensitive(False)
|
||||
elif src.get_name() == "type-remote-xen":
|
||||
self.window.get_widget("remote-xen-options").set_sensitive(True)
|
||||
self.window.get_widget("other-hv-options").set_sensitive(False)
|
||||
else:
|
||||
self.window.get_widget("remote-xen-options").set_sensitive(False)
|
||||
self.window.get_widget("other-hv-options").set_sensitive(True)
|
||||
|
||||
def open_connection(self,src):
|
||||
uri = None
|
||||
|
||||
if self.window.get_widget("type-local-xen").get_active():
|
||||
uri = None
|
||||
elif self.window.get_widget("type-remote-xen").get_active():
|
||||
protocol = "http"
|
||||
if self.window.get_widget("remote-xen-secure").get_active():
|
||||
protocol = "https"
|
||||
uri = protocol + "://" + self.window.get_widget("remote-xen-host").get_text() + ":" + self.window.get_widget("remote-xen-port").get_text()
|
||||
else:
|
||||
uri = self.window.get_widget("other-hv-uri").get_text()
|
||||
|
||||
con = self.engine.get_connection(uri, self.window.get_widget("option-read-only").get_active())
|
||||
con.show_manager()
|
||||
self.close()
|
|
@ -0,0 +1,121 @@
|
|||
|
||||
import libvirt
|
||||
|
||||
from virtManager.stats import vmmStats
|
||||
from virtManager.manager import vmmManager
|
||||
from virtManager.details import vmmDetails
|
||||
from virtManager.console import vmmConsole
|
||||
|
||||
class vmmConnection:
|
||||
def __init__(self, engine, config, uri, readOnly):
|
||||
self.engine = engine
|
||||
self.config = config
|
||||
|
||||
if readOnly:
|
||||
self.vmm = libvirt.openReadOnly(uri)
|
||||
else:
|
||||
self.vmm = libvirt.open(uri)
|
||||
|
||||
self.windowManager = None
|
||||
self.windowDetails = {}
|
||||
self.windowConsole = {}
|
||||
self.vms = {}
|
||||
|
||||
self.callbacks = { "vm_added": [], "vm_removed": [], "vm_updated": [] }
|
||||
self.stats = vmmStats(config, self)
|
||||
|
||||
def get_stats(self):
|
||||
return self.stats
|
||||
|
||||
def show_about(self):
|
||||
self.engine.show_about()
|
||||
|
||||
def show_preferences(self):
|
||||
self.engine.show_preferences()
|
||||
|
||||
def show_manager(self):
|
||||
if self.windowManager == None:
|
||||
self.windowManager = vmmManager(self.config, self)
|
||||
self.windowManager.show()
|
||||
|
||||
def get_host_info(self):
|
||||
return self.vmm.getInfo()
|
||||
|
||||
def show_details(self, vmuuid):
|
||||
if not(self.windowDetails.has_key(vmuuid)):
|
||||
self.windowDetails[vmuuid] = vmmDetails(self.config, self, self.vms[vmuuid], vmuuid)
|
||||
|
||||
self.windowDetails[vmuuid].show()
|
||||
|
||||
def show_console(self, vmuuid):
|
||||
if not(self.windowConsole.has_key(vmuuid)):
|
||||
self.windowConsole[vmuuid] = vmmConsole(self.config, self, self.vms[vmuuid], vmuuid)
|
||||
|
||||
self.windowConsole[vmuuid].show()
|
||||
|
||||
def show_open_connection(self):
|
||||
self.engine.show_open_connection()
|
||||
|
||||
def connect_to_signal(self, name, callback):
|
||||
if not(self.callbacks.has_key(name)):
|
||||
raise "unknown signal " + name + "requested"
|
||||
|
||||
self.callbacks[name].append(callback)
|
||||
|
||||
if name == "vm_removed":
|
||||
for uuid in self.vms.keys():
|
||||
self.notify_vm_added(uuid, self.vms[uuid].name())
|
||||
|
||||
def disconnect_from_signal(self, name, callback):
|
||||
for i in len(self.callbacks[name]):
|
||||
if self.callbacks[i] == callback:
|
||||
del self.callbacks[i:i]
|
||||
|
||||
|
||||
def notify_vm_added(self, uuid, name):
|
||||
for cb in self.callbacks["vm_added"]:
|
||||
cb(uuid, name)
|
||||
|
||||
def notify_vm_removed(self, uuid):
|
||||
for cb in self.callbacks["vm_removed"]:
|
||||
cb(uuid)
|
||||
|
||||
def notify_vm_updated(self, uuid):
|
||||
for cb in self.callbacks["vm_updated"]:
|
||||
cb(uuid)
|
||||
|
||||
def tick(self):
|
||||
doms = self.vmm.listDomainsID()
|
||||
newVms = {}
|
||||
if doms != None:
|
||||
for id in doms:
|
||||
vm = self.vmm.lookupByID(id)
|
||||
newVms[self.uuidstr(vm.UUID())] = vm
|
||||
|
||||
for uuid in self.vms.keys():
|
||||
if not(newVms.has_key(uuid)):
|
||||
del self.vms[uuid]
|
||||
self.notify_vm_removed(uuid)
|
||||
|
||||
for uuid in newVms.keys():
|
||||
if not(self.vms.has_key(uuid)):
|
||||
self.vms[uuid] = newVms[uuid]
|
||||
self.notify_vm_added(uuid, newVms[uuid].name())
|
||||
|
||||
for uuid in self.vms.keys():
|
||||
self.stats.update(uuid, self.vms[uuid])
|
||||
self.notify_vm_updated(uuid)
|
||||
|
||||
return 1
|
||||
|
||||
def uuidstr(self, rawuuid):
|
||||
hex = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f']
|
||||
uuid = []
|
||||
for i in range(16):
|
||||
uuid.append(hex[((ord(rawuuid[i]) >> 4) & 0xf)])
|
||||
uuid.append(hex[(ord(rawuuid[i]) & 0xf)])
|
||||
if i == 3 or i == 5 or i == 7 or i == 9:
|
||||
uuid.append('-')
|
||||
return "".join(uuid)
|
||||
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
|
||||
import gtk.glade
|
||||
import libvirt
|
||||
|
||||
class vmmConsole:
|
||||
def __init__(self, config, connection, vm, vmuuid):
|
||||
self.window = gtk.glade.XML(config.get_glade_file(), "vmm-console")
|
||||
self.config = config
|
||||
self.connection = connection
|
||||
self.vm = vm
|
||||
self.vmuuid = vmuuid
|
||||
self.lastStatus = None
|
||||
|
||||
topwin = self.window.get_widget("vmm-console")
|
||||
topwin.hide()
|
||||
topwin.set_title(vm.name() + " " + topwin.get_title())
|
||||
|
||||
self.window.get_widget("control-run").set_icon_widget(gtk.Image())
|
||||
self.window.get_widget("control-run").get_icon_widget().set_from_file(config.get_icon_dir() + "/icon_run.png")
|
||||
|
||||
self.window.get_widget("control-pause").set_icon_widget(gtk.Image())
|
||||
self.window.get_widget("control-pause").get_icon_widget().set_from_file(config.get_icon_dir() + "/icon_pause.png")
|
||||
|
||||
self.window.get_widget("control-shutdown").set_icon_widget(gtk.Image())
|
||||
#self.window.get_widget("control-shutdown").get_icon_widget().set_from_file(config.get_icon_dir() + "/icon_run.png")
|
||||
|
||||
self.window.get_widget("control-terminal").set_icon_widget(gtk.Image())
|
||||
self.window.get_widget("control-terminal").get_icon_widget().set_from_file(config.get_icon_dir() + "/icon_launch_term.png")
|
||||
|
||||
self.window.get_widget("control-snapshot").set_icon_widget(gtk.Image())
|
||||
self.window.get_widget("control-snapshot").get_icon_widget().set_from_file(config.get_icon_dir() + "/icon_snapshot.png")
|
||||
|
||||
|
||||
self.window.signal_autoconnect({
|
||||
"on_vmm_console_delete_event": self.close,
|
||||
|
||||
"on_control_run_clicked": self.control_vm_run,
|
||||
"on_control_shutdown_clicked": self.control_vm_shutdown,
|
||||
"on_control_pause_toggled": self.control_vm_pause,
|
||||
|
||||
"on_control_terminal_clicked": self.control_vm_terminal,
|
||||
"on_control_snapshot_clicked": self.control_vm_snapshot,
|
||||
"on_control_details_clicked": self.control_vm_details,
|
||||
})
|
||||
|
||||
self.connection.connect_to_signal("vm_updated", self.vm_updated)
|
||||
self.refresh_status()
|
||||
|
||||
def show(self):
|
||||
dialog = self.window.get_widget("vmm-console")
|
||||
dialog.show_all()
|
||||
dialog.present()
|
||||
|
||||
def close(self,ignore1=None,ignore2=None):
|
||||
self.window.get_widget("vmm-console").hide()
|
||||
return 1
|
||||
|
||||
def control_vm_run(self, src):
|
||||
return 0
|
||||
|
||||
def control_vm_shutdown(self, src):
|
||||
info = self.vm.info()
|
||||
if not(info[0] in [ libvirt.VIR_DOMAIN_SHUTDOWN, libvirt.VIR_DOMAIN_SHUTOFF ]):
|
||||
self.vm.shutdown()
|
||||
else:
|
||||
print "Shutdown requested, but machine is already shutting down / shutoff"
|
||||
|
||||
def control_vm_pause(self, src):
|
||||
info = self.vm.info()
|
||||
if info[0] in [ libvirt.VIR_DOMAIN_SHUTDOWN, libvirt.VIR_DOMAIN_SHUTOFF, libvirt.VIR_DOMAIN_CRASHED ]:
|
||||
print "Pause/resume requested, but machine is shutdown / shutoff"
|
||||
else:
|
||||
if info[0] in [ libvirt.VIR_DOMAIN_PAUSED ]:
|
||||
if not src.get_active():
|
||||
self.vm.resume()
|
||||
else:
|
||||
print "Pause requested, but machine is already paused"
|
||||
else:
|
||||
if src.get_active():
|
||||
self.vm.suspend()
|
||||
else:
|
||||
print "Resume requested, but machine is already running"
|
||||
|
||||
|
||||
def control_vm_terminal(self, src):
|
||||
return 0
|
||||
|
||||
def control_vm_snapshot(self, src):
|
||||
return 0
|
||||
|
||||
def control_vm_details(self, src):
|
||||
self.connection.show_details(self.vmuuid)
|
||||
|
||||
def vm_updated(self, uuid):
|
||||
if uuid == self.vmuuid:
|
||||
self.refresh_status()
|
||||
|
||||
def refresh_status(self):
|
||||
info = self.vm.info()
|
||||
status = info[0]
|
||||
|
||||
if self.lastStatus == status:
|
||||
return
|
||||
|
||||
if status == libvirt.VIR_DOMAIN_SHUTOFF:
|
||||
self.window.get_widget("control-run").set_sensitive(True)
|
||||
else:
|
||||
self.window.get_widget("control-run").set_sensitive(False)
|
||||
|
||||
if status in [ libvirt.VIR_DOMAIN_SHUTDOWN, libvirt.VIR_DOMAIN_SHUTOFF ]:
|
||||
self.window.get_widget("control-pause").set_sensitive(False)
|
||||
self.window.get_widget("control-shutdown").set_sensitive(False)
|
||||
self.window.get_widget("control-terminal").set_sensitive(False)
|
||||
self.window.get_widget("control-snapshot").set_sensitive(False)
|
||||
else:
|
||||
self.window.get_widget("control-pause").set_sensitive(True)
|
||||
self.window.get_widget("control-shutdown").set_sensitive(True)
|
||||
self.window.get_widget("control-terminal").set_sensitive(True)
|
||||
self.window.get_widget("control-snapshot").set_sensitive(True)
|
||||
if status == libvirt.VIR_DOMAIN_PAUSED:
|
||||
self.window.get_widget("control-pause").set_active(True)
|
||||
else:
|
||||
self.window.get_widget("control-pause").set_active(False)
|
||||
|
||||
self.lastStatus = status
|
||||
|
|
@ -0,0 +1,270 @@
|
|||
|
||||
import gtk
|
||||
import gtk.glade
|
||||
|
||||
import matplotlib
|
||||
matplotlib.use('GTK')
|
||||
# Obnoxious matplotlib sets its own icon as the default
|
||||
# which is a totally inappropriate action for a library
|
||||
# to take
|
||||
#gtk.window_set_default_icon(None)
|
||||
|
||||
from matplotlib.figure import Figure
|
||||
from matplotlib.axes import Subplot
|
||||
from matplotlib.backends.backend_gtk import FigureCanvasGTK, NavigationToolbar
|
||||
|
||||
from matplotlib.numerix import arange, sin, pi
|
||||
|
||||
class vmmDetails:
|
||||
def __init__(self, config, connection, vm, vmuuid):
|
||||
self.window = gtk.glade.XML(config.get_glade_file(), "vmm-details")
|
||||
self.config = config
|
||||
self.connection = connection
|
||||
self.vm = vm
|
||||
self.vmuuid = vmuuid
|
||||
self.lastStatus = None
|
||||
|
||||
topwin = self.window.get_widget("vmm-details")
|
||||
topwin.hide()
|
||||
topwin.set_title(vm.name() + " " + topwin.get_title())
|
||||
|
||||
self.window.get_widget("overview-name").set_text(vm.name())
|
||||
self.window.get_widget("overview-uuid").set_text(vmuuid)
|
||||
|
||||
self.window.get_widget("control-run").set_icon_widget(gtk.Image())
|
||||
self.window.get_widget("control-run").get_icon_widget().set_from_file(config.get_icon_dir() + "/icon_run.png")
|
||||
|
||||
self.window.get_widget("control-pause").set_icon_widget(gtk.Image())
|
||||
self.window.get_widget("control-pause").get_icon_widget().set_from_file(config.get_icon_dir() + "/icon_pause.png")
|
||||
|
||||
self.window.get_widget("control-shutdown").set_icon_widget(gtk.Image())
|
||||
#self.window.get_widget("control-shutdown").get_icon_widget().set_from_file(config.get_icon_dir() + "/icon_run.png")
|
||||
|
||||
self.window.get_widget("control-terminal").set_icon_widget(gtk.Image())
|
||||
self.window.get_widget("control-terminal").get_icon_widget().set_from_file(config.get_icon_dir() + "/icon_launch_term.png")
|
||||
|
||||
self.window.get_widget("control-snapshot").set_icon_widget(gtk.Image())
|
||||
self.window.get_widget("control-snapshot").get_icon_widget().set_from_file(config.get_icon_dir() + "/icon_snapshot.png")
|
||||
|
||||
self.window.get_widget("hw-panel").set_show_tabs(False)
|
||||
|
||||
hwListModel = gtk.ListStore(int, str, gtk.gdk.Pixbuf)
|
||||
self.window.get_widget("hw-list").set_model(hwListModel)
|
||||
|
||||
hwListModel.append([0, "Processor", gtk.gdk.pixbuf_new_from_file(config.get_icon_dir() + "/icon_cpu.png")])
|
||||
#hwListModel.append([1, "Memory", gtk.gdk.pixbuf_new_from_file(config.get_icon_dir() + "/icon_ram.png")])
|
||||
hwListModel.append([1, "Memory", gtk.gdk.pixbuf_new_from_file(config.get_icon_dir() + "/icon_cpu.png")])
|
||||
hwListModel.append([2, "Disk", gtk.gdk.pixbuf_new_from_file(config.get_icon_dir() + "/icon_hdd.png")])
|
||||
hwListModel.append([3, "Network", gtk.gdk.pixbuf_new_from_file(config.get_icon_dir() + "/icon_ethernet.png")])
|
||||
hwListModel.append([4, "Add hardware", gtk.gdk.pixbuf_new_from_file(config.get_icon_dir() + "/icon_addnew.png")])
|
||||
|
||||
self.window.get_widget("hw-list").get_selection().connect("changed", self.hw_selected)
|
||||
|
||||
|
||||
hwCol = gtk.TreeViewColumn("Hardware")
|
||||
hw_txt = gtk.CellRendererText()
|
||||
hw_img = gtk.CellRendererPixbuf()
|
||||
hwCol.pack_start(hw_txt, True)
|
||||
hwCol.pack_start(hw_img, False)
|
||||
hwCol.add_attribute(hw_txt, 'text', 1)
|
||||
hwCol.add_attribute(hw_img, 'pixbuf', 2)
|
||||
|
||||
self.window.get_widget("hw-list").append_column(hwCol)
|
||||
|
||||
|
||||
self.cpu_usage_figure = Figure()
|
||||
self.cpu_usage_graph = self.cpu_usage_figure.add_subplot(111)
|
||||
self.cpu_usage_graph.set_autoscale_on(False)
|
||||
self.cpu_usage_line = None
|
||||
self.cpu_usage_line_avg = None
|
||||
self.cpu_usage_canvas = FigureCanvasGTK(self.cpu_usage_figure)
|
||||
self.cpu_usage_canvas.show()
|
||||
self.window.get_widget("graph-table").attach(self.cpu_usage_canvas, 1, 2, 0, 1)
|
||||
|
||||
self.memory_usage_figure = Figure()
|
||||
self.memory_usage_graph = self.memory_usage_figure.add_subplot(111)
|
||||
self.memory_usage_graph.set_autoscale_on(False)
|
||||
self.memory_usage_line = None
|
||||
self.memory_usage_canvas = FigureCanvasGTK(self.memory_usage_figure)
|
||||
self.memory_usage_canvas.show()
|
||||
self.window.get_widget("graph-table").attach(self.memory_usage_canvas, 1, 2, 1, 2)
|
||||
|
||||
self.network_traffic_figure = Figure()
|
||||
self.network_traffic_graph = self.network_traffic_figure.add_subplot(111)
|
||||
self.network_traffic_graph.set_autoscale_on(False)
|
||||
self.network_traffic_line = None
|
||||
self.network_traffic_canvas = FigureCanvasGTK(self.network_traffic_figure)
|
||||
self.network_traffic_canvas.show()
|
||||
self.window.get_widget("graph-table").attach(self.network_traffic_canvas, 1, 2, 3, 4)
|
||||
|
||||
self.config.on_stats_history_length_changed(self.change_graph_ranges)
|
||||
|
||||
self.window.signal_autoconnect({
|
||||
"on_close_details_clicked": self.close,
|
||||
"on_vmm_details_delete_event": self.close,
|
||||
|
||||
"on_control_run_clicked": self.control_vm_run,
|
||||
"on_control_shutdown_clicked": self.control_vm_shutdown,
|
||||
"on_control_pause_toggled": self.control_vm_pause,
|
||||
|
||||
"on_control_terminal_clicked": self.control_vm_terminal,
|
||||
"on_control_snapshot_clicked": self.control_vm_snapshot,
|
||||
})
|
||||
|
||||
self.connection.connect_to_signal("vm_updated", self.refresh_overview)
|
||||
self.change_graph_ranges()
|
||||
self.refresh_overview(vmuuid)
|
||||
self.hw_selected()
|
||||
|
||||
def show(self):
|
||||
dialog = self.window.get_widget("vmm-details")
|
||||
dialog.show_all()
|
||||
dialog.present()
|
||||
|
||||
def close(self,ignore1=None,ignore2=None):
|
||||
self.window.get_widget("vmm-details").hide()
|
||||
return 1
|
||||
|
||||
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:
|
||||
self.window.get_widget("hw-panel").set_sensitive(True)
|
||||
self.window.get_widget("hw-panel").set_current_page(active[0].get_value(active[1], 0))
|
||||
else:
|
||||
self.window.get_widget("hw-panel").set_sensitive(False)
|
||||
|
||||
def control_vm_run(self, src):
|
||||
return 0
|
||||
|
||||
def control_vm_shutdown(self, src):
|
||||
if not(self.connection.get_stats().run_status(self.vmuuid) in [ "shutdown", "shutoff" ]):
|
||||
self.vm.shutdown()
|
||||
else:
|
||||
print "Shutdown requested, but machine is already shutting down / shutoff"
|
||||
|
||||
def control_vm_pause(self, src):
|
||||
if self.connection.get_stats().run_status(self.vmuuid) in [ "shutdown", "shutoff" ]:
|
||||
print "Pause/resume requested, but machine is shutdown / shutoff"
|
||||
else:
|
||||
if self.connection.get_stats().run_status(self.vmuuid) in [ "paused" ]:
|
||||
if not src.get_active():
|
||||
self.vm.resume()
|
||||
else:
|
||||
print "Pause requested, but machine is already paused"
|
||||
else:
|
||||
if src.get_active():
|
||||
self.vm.suspend()
|
||||
else:
|
||||
print "Resume requested, but machine is already running"
|
||||
|
||||
|
||||
def control_vm_terminal(self, src):
|
||||
return 0
|
||||
|
||||
def control_vm_snapshot(self, src):
|
||||
return 0
|
||||
|
||||
def change_graph_ranges(self, ignore1=None,ignore2=None,ignore3=None,ignore4=None):
|
||||
self.cpu_usage_graph.clear()
|
||||
#self.cpu_usage_graph.set_xlabel('History')
|
||||
#self.cpu_usage_graph.set_ylabel('% utilization')
|
||||
self.cpu_usage_graph.grid(True)
|
||||
self.cpu_usage_line = None
|
||||
|
||||
self.memory_usage_graph.clear()
|
||||
#self.memory_usage_graph.set_xlabel('History')
|
||||
#self.memory_usage_graph.set_ylabel('% utilization')
|
||||
self.memory_usage_graph.grid(True)
|
||||
self.memory_usage_line = None
|
||||
|
||||
self.network_traffic_graph.clear()
|
||||
#self.network_traffic_graph.set_xlabel('History')
|
||||
#self.network_traffic_graph.set_ylabel('% utilization')
|
||||
self.network_traffic_graph.grid(True)
|
||||
self.network_traffic_line = None
|
||||
|
||||
def update_widget_states(self, status):
|
||||
if self.lastStatus == status:
|
||||
return
|
||||
|
||||
if status == "shutoff":
|
||||
self.window.get_widget("control-run").set_sensitive(True)
|
||||
else:
|
||||
self.window.get_widget("control-run").set_sensitive(False)
|
||||
|
||||
if status in [ "shutoff", "shutdown" ]:
|
||||
self.window.get_widget("control-pause").set_sensitive(False)
|
||||
self.window.get_widget("control-shutdown").set_sensitive(False)
|
||||
self.window.get_widget("control-terminal").set_sensitive(False)
|
||||
self.window.get_widget("control-snapshot").set_sensitive(False)
|
||||
else:
|
||||
self.window.get_widget("control-pause").set_sensitive(True)
|
||||
self.window.get_widget("control-shutdown").set_sensitive(True)
|
||||
self.window.get_widget("control-terminal").set_sensitive(True)
|
||||
self.window.get_widget("control-snapshot").set_sensitive(True)
|
||||
if status == "paused":
|
||||
self.window.get_widget("control-pause").set_active(True)
|
||||
else:
|
||||
self.window.get_widget("control-pause").set_active(False)
|
||||
|
||||
self.lastStatus = status
|
||||
|
||||
def refresh_overview(self, vmuuid):
|
||||
if not(vmuuid == self.vmuuid):
|
||||
return
|
||||
|
||||
status = self.connection.get_stats().run_status(vmuuid)
|
||||
self.update_widget_states(status)
|
||||
|
||||
self.window.get_widget("overview-status-text").set_text(status)
|
||||
self.window.get_widget("overview-status-icon").set_from_pixbuf(self.connection.get_stats().run_status_icon(vmuuid))
|
||||
self.window.get_widget("overview-cpu-usage-text").set_text("%d %%" % self.connection.get_stats().cpu_time_percentage(vmuuid))
|
||||
self.window.get_widget("overview-memory-usage-text").set_text("%d MB of %d MB" % (self.connection.get_stats().current_memory(vmuuid)/1024, self.connection.get_stats().host_memory_size()/1024))
|
||||
|
||||
history_len = self.config.get_stats_history_length()
|
||||
cpu_vector = self.connection.get_stats().cpu_time_vector(vmuuid)
|
||||
cpu_vector.reverse()
|
||||
cpu_vector_avg = self.connection.get_stats().cpu_time_moving_avg_vector(vmuuid)
|
||||
cpu_vector_avg.reverse()
|
||||
if self.cpu_usage_line == None:
|
||||
self.cpu_usage_line = self.cpu_usage_graph.plot(cpu_vector)
|
||||
self.cpu_usage_line_avg = self.cpu_usage_graph.plot(cpu_vector_avg)
|
||||
self.cpu_usage_graph.set_xlim(0, history_len)
|
||||
self.cpu_usage_graph.set_ylim(0, 100)
|
||||
else:
|
||||
self.cpu_usage_line[0].set_ydata(cpu_vector)
|
||||
self.cpu_usage_line_avg[0].set_ydata(cpu_vector_avg)
|
||||
self.cpu_usage_graph.set_xlim(0, history_len)
|
||||
self.cpu_usage_graph.set_ylim(0, 100)
|
||||
self.cpu_usage_graph.set_yticklabels(["0","","","","","100"])
|
||||
self.cpu_usage_graph.set_xticklabels([])
|
||||
self.cpu_usage_canvas.draw()
|
||||
|
||||
history_len = self.config.get_stats_history_length()
|
||||
memory_vector = self.connection.get_stats().current_memory_vector(vmuuid)
|
||||
memory_vector.reverse()
|
||||
if self.memory_usage_line == None:
|
||||
self.memory_usage_line = self.memory_usage_graph.plot(memory_vector)
|
||||
self.memory_usage_graph.set_xlim(0, history_len)
|
||||
self.memory_usage_graph.set_ylim(0, 100)
|
||||
else:
|
||||
self.memory_usage_line[0].set_ydata(memory_vector)
|
||||
self.memory_usage_graph.set_xlim(0, history_len)
|
||||
self.memory_usage_graph.set_ylim(0, 100)
|
||||
self.memory_usage_graph.set_yticklabels(["0","","","","","100"])
|
||||
self.memory_usage_graph.set_xticklabels([])
|
||||
self.memory_usage_canvas.draw()
|
||||
|
||||
history_len = self.config.get_stats_history_length()
|
||||
#if self.network_traffic_line == None:
|
||||
#self.network_traffic_line = self.network_traffic_graph.plot(self.connection.get_stats().network_traffic_vector(vmuuid))
|
||||
#else:
|
||||
#self.network_traffic_line[0].set_ydata(self.connection.get_stats().network_traffic_vector(vmuuid))
|
||||
self.network_traffic_graph.set_xlim(0, history_len)
|
||||
self.network_traffic_graph.set_ylim(0, 100)
|
||||
self.network_traffic_graph.set_yticklabels(["0","","","","","100"])
|
||||
self.network_traffic_graph.set_xticklabels([])
|
||||
self.network_traffic_canvas.draw()
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
import gobject
|
||||
|
||||
from virtManager.about import vmmAbout
|
||||
from virtManager.connect import vmmConnect
|
||||
from virtManager.connection import vmmConnection
|
||||
from virtManager.preferences import vmmPreferences
|
||||
|
||||
class vmmEngine:
|
||||
def __init__(self, config):
|
||||
self.windowOpenConnection = None
|
||||
self.windowPreferences = None
|
||||
self.windowAbout = None
|
||||
|
||||
self.connections = {}
|
||||
|
||||
self.timer = None
|
||||
self.last_timeout = 0
|
||||
|
||||
self.config = config
|
||||
self.config.on_stats_update_interval_changed(self.reschedule_timer)
|
||||
|
||||
self.schedule_timer()
|
||||
self.tick()
|
||||
|
||||
|
||||
def reschedule_timer(self, ignore1,ignore2,ignore3,ignore4):
|
||||
self.schedule_timer()
|
||||
|
||||
def schedule_timer(self):
|
||||
interval = self.get_config().get_stats_update_interval() * 1000
|
||||
|
||||
if self.timer != None:
|
||||
gobject.source_remove(self.timer)
|
||||
self.timer = None
|
||||
|
||||
self.timer = gobject.timeout_add(interval, self.tick)
|
||||
|
||||
def tick(self):
|
||||
for uri in self.connections.keys():
|
||||
try:
|
||||
self.connections[uri].tick()
|
||||
except:
|
||||
print str(sys.exc_info()[0]) + " " + str(sys.exc_info()[1])
|
||||
print "Error refreshing connection " + uri
|
||||
return 1
|
||||
|
||||
def change_timer_interval(self,ignore1,ignore2,ignore3,ignore4):
|
||||
gobject.source_remove(self.timer)
|
||||
self.schedule_timer()
|
||||
|
||||
def get_config(self):
|
||||
return self.config
|
||||
|
||||
def show_about(self):
|
||||
if self.windowAbout == None:
|
||||
self.windowAbout = vmmAbout(self.get_config())
|
||||
self.windowAbout.show()
|
||||
|
||||
def show_preferences(self):
|
||||
if self.windowPreferences == None:
|
||||
self.windowPreferences = vmmPreferences(self.get_config())
|
||||
self.windowPreferences.show()
|
||||
|
||||
def show_open_connection(self):
|
||||
if self.windowOpenConnection == None:
|
||||
self.windowOpenConnection = vmmConnect(self.get_config(), self)
|
||||
self.windowOpenConnection.show()
|
||||
|
||||
def show_console(self, uri, uuid):
|
||||
con = self.get_connection(uri)
|
||||
con.show_console(uuid)
|
||||
|
||||
def show_details(self, uri, uuid):
|
||||
con = self.get_connection(uri)
|
||||
con.show_details(uuid)
|
||||
|
||||
def show_manager(self, uri):
|
||||
con = self.get_connection(uri)
|
||||
con.show_manager()
|
||||
|
||||
def get_connection(self, uri, readOnly=True):
|
||||
key = uri
|
||||
if key == None or key == "":
|
||||
key = "__default__"
|
||||
|
||||
if not(self.connections.has_key(key)):
|
||||
self.connections[key] = vmmConnection(self, self.get_config(), uri, readOnly)
|
||||
self.connections[key].tick()
|
||||
return self.connections[key]
|
|
@ -0,0 +1,380 @@
|
|||
|
||||
import gtk
|
||||
import gtk.glade
|
||||
|
||||
VMLIST_SORT_NAME = 1
|
||||
VMLIST_SORT_CPU_USAGE = 2
|
||||
VMLIST_SORT_MEMORY_USAGE = 3
|
||||
VMLIST_SORT_DISK_USAGE = 4
|
||||
VMLIST_SORT_NETWORK_USAGE = 5
|
||||
|
||||
class vmmManager:
|
||||
def __init__(self, config, connection):
|
||||
self.window = gtk.glade.XML(config.get_glade_file(), "vmm-manager")
|
||||
self.config = config
|
||||
self.connection = connection
|
||||
self.prepare_vmlist()
|
||||
|
||||
self.connection.connect_to_signal("vm_added", self.vm_added)
|
||||
self.connection.connect_to_signal("vm_removed", self.vm_removed)
|
||||
self.connection.connect_to_signal("vm_updated", self.vm_updated)
|
||||
|
||||
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_memory_usage_visible_changed(self.toggle_memory_usage_visible_widget)
|
||||
self.config.on_vmlist_disk_usage_visible_changed(self.toggle_disk_usage_visible_widget)
|
||||
self.config.on_vmlist_network_traffic_visible_changed(self.toggle_network_traffic_visible_widget)
|
||||
|
||||
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_memory_usage").set_active(self.config.is_vmlist_memory_usage_visible())
|
||||
self.window.get_widget("menu_view_disk_usage").set_active(self.config.is_vmlist_disk_usage_visible())
|
||||
self.window.get_widget("menu_view_network_traffic").set_active(self.config.is_vmlist_network_traffic_visible())
|
||||
|
||||
self.window.get_widget("menu_file_new").set_sensitive(False)
|
||||
self.window.get_widget("vm-new").set_sensitive(False)
|
||||
self.window.get_widget("vm-view").set_sensitive(False)
|
||||
self.window.get_widget("vm-view").set_active(0)
|
||||
|
||||
self.vmmenu = gtk.Menu()
|
||||
self.vmmenu_items = {}
|
||||
|
||||
self.vmmenu_items["details"] = gtk.MenuItem("_Details")
|
||||
self.vmmenu_items["details"].connect("activate", self.show_vm_details)
|
||||
self.vmmenu_items["details"].show()
|
||||
self.vmmenu.add(self.vmmenu_items["details"])
|
||||
|
||||
self.vmmenu_items["open"] = gtk.MenuItem("Open")
|
||||
self.vmmenu_items["open"].connect("activate", self.open_vm_console)
|
||||
self.vmmenu_items["open"].show()
|
||||
self.vmmenu.add(self.vmmenu_items["open"])
|
||||
|
||||
self.vmmenu.show_all()
|
||||
|
||||
|
||||
self.window.signal_autoconnect({
|
||||
"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_memory_usage_activate" : self.toggle_memory_usage_visible_conf,
|
||||
"on_menu_view_disk_usage_activate" : self.toggle_disk_usage_visible_conf,
|
||||
"on_menu_view_network_traffic_activate" : self.toggle_network_traffic_visible_conf,
|
||||
|
||||
"on_vm_manager_delete_event": self.exit_app,
|
||||
"on_menu_file_open_connection_activate": self.open_connection,
|
||||
"on_menu_file_quit_activate": self.exit_app,
|
||||
"on_vmm_close_clicked": self.exit_app,
|
||||
"on_vm_details_clicked": self.show_vm_details,
|
||||
"on_vm_open_clicked": self.open_vm_console,
|
||||
"on_menu_edit_details_activate": self.show_vm_details,
|
||||
|
||||
"on_vm_list_row_activated": self.open_vm_console,
|
||||
|
||||
"on_vm_list_button_press_event": self.popup_vm_menu,
|
||||
|
||||
"on_menu_edit_preferences_activate": self.show_preferences,
|
||||
"on_menu_help_about_activate": self.show_about,
|
||||
})
|
||||
|
||||
self.vm_selected(None)
|
||||
self.window.get_widget("vm-list").get_selection().connect("changed", self.vm_selected)
|
||||
|
||||
|
||||
def show(self):
|
||||
win = self.window.get_widget("vmm-manager")
|
||||
win.show_all()
|
||||
win.present()
|
||||
|
||||
|
||||
def exit_app(self, ignore=None,ignore2=None):
|
||||
gtk.main_quit()
|
||||
|
||||
def open_connection(self, src=None):
|
||||
self.connection.show_open_connection()
|
||||
|
||||
def vm_added(self, vmuuid, name):
|
||||
vmlist = self.window.get_widget("vm-list")
|
||||
model = vmlist.get_model()
|
||||
|
||||
dup = 0
|
||||
for row in range(model.iter_n_children(None)):
|
||||
vm = model.get_value(model.iter_nth_child(None, row), 0)
|
||||
if vm == vmuuid:
|
||||
dup = 1
|
||||
|
||||
if dup != 1:
|
||||
model.append([vmuuid, name])
|
||||
|
||||
|
||||
def vm_removed(self, vmuuid):
|
||||
vmlist = self.window.get_widget("vm-list")
|
||||
model = vmlist.get_model()
|
||||
|
||||
dup = 0
|
||||
for row in range(model.iter_n_children(None)):
|
||||
vm = model.get_value(model.iter_nth_child(None, row), 0)
|
||||
if vm == vmuuid:
|
||||
model.remove(model.iter_nth_child(None, row))
|
||||
break
|
||||
|
||||
def vm_updated(self, vmuuid):
|
||||
vmlist = self.window.get_widget("vm-list")
|
||||
model = vmlist.get_model()
|
||||
|
||||
for row in range(model.iter_n_children(None)):
|
||||
iter = model.iter_nth_child(None, row)
|
||||
if model.get_value(iter, 0) == vmuuid:
|
||||
model.row_changed(str(row), iter)
|
||||
|
||||
def current_vm(self):
|
||||
vmlist = self.window.get_widget("vm-list")
|
||||
selection = vmlist.get_selection()
|
||||
active = selection.get_selected()
|
||||
if active[1] != None:
|
||||
return active[0].get_value(active[1], 0)
|
||||
return None
|
||||
|
||||
def show_vm_details(self,ignore):
|
||||
self.connection.show_details(self.current_vm())
|
||||
|
||||
def open_vm_console(self,ignore,ignore2=None,ignore3=None):
|
||||
self.connection.show_console(self.current_vm())
|
||||
|
||||
|
||||
def vm_selected(self, selection):
|
||||
if selection == None or selection.count_selected_rows() == 0:
|
||||
self.window.get_widget("vm-delete").set_sensitive(False)
|
||||
self.window.get_widget("vm-details").set_sensitive(False)
|
||||
self.window.get_widget("vm-open").set_sensitive(False)
|
||||
self.window.get_widget("menu_edit_delete").set_sensitive(False)
|
||||
self.window.get_widget("menu_edit_details").set_sensitive(False)
|
||||
else:
|
||||
#self.window.get_widget("vm-delete").set_sensitive(True)
|
||||
self.window.get_widget("vm-delete").set_sensitive(False)
|
||||
self.window.get_widget("vm-details").set_sensitive(True)
|
||||
self.window.get_widget("vm-open").set_sensitive(True)
|
||||
#self.window.get_widget("menu_edit_delete").set_sensitive(True)
|
||||
self.window.get_widget("menu_edit_delete").set_sensitive(False)
|
||||
self.window.get_widget("menu_edit_details").set_sensitive(True)
|
||||
|
||||
def popup_vm_menu(self, widget, event):
|
||||
vm = self.current_vm()
|
||||
if vm != None:
|
||||
if event.button == 3:
|
||||
self.vmmenu.popup(None, None, None, 0, event.time)
|
||||
|
||||
def show_about(self, src):
|
||||
self.connection.show_about()
|
||||
|
||||
def show_preferences(self, src):
|
||||
self.connection.show_preferences()
|
||||
|
||||
def prepare_vmlist(self):
|
||||
vmlist = self.window.get_widget("vm-list")
|
||||
|
||||
model = gtk.ListStore(str, str)
|
||||
vmlist.set_model(model)
|
||||
|
||||
nameCol = gtk.TreeViewColumn("Name")
|
||||
statusCol = gtk.TreeViewColumn("Status")
|
||||
cpuUsageCol = gtk.TreeViewColumn("CPU usage")
|
||||
memoryUsageCol = gtk.TreeViewColumn("Memory usage")
|
||||
diskUsageCol = gtk.TreeViewColumn("Disk usage")
|
||||
networkTrafficCol = gtk.TreeViewColumn("Network traffic")
|
||||
|
||||
name_txt = gtk.CellRendererText()
|
||||
nameCol.pack_start(name_txt, True)
|
||||
nameCol.add_attribute(name_txt, 'text', 1)
|
||||
nameCol.set_sort_column_id(VMLIST_SORT_NAME)
|
||||
|
||||
vmlist.append_column(nameCol)
|
||||
vmlist.append_column(statusCol)
|
||||
vmlist.append_column(cpuUsageCol)
|
||||
vmlist.append_column(memoryUsageCol)
|
||||
vmlist.append_column(diskUsageCol)
|
||||
vmlist.append_column(networkTrafficCol)
|
||||
|
||||
status_txt = gtk.CellRendererText()
|
||||
status_icon = gtk.CellRendererPixbuf()
|
||||
statusCol.pack_start(status_icon, False)
|
||||
statusCol.pack_start(status_txt, False)
|
||||
statusCol.set_cell_data_func(status_txt, self.status_text, None)
|
||||
statusCol.set_cell_data_func(status_icon, self.status_icon, None)
|
||||
statusCol.set_visible(self.config.is_vmlist_status_visible())
|
||||
|
||||
|
||||
|
||||
|
||||
cpuUsage_txt = gtk.CellRendererText()
|
||||
cpuUsage_img = gtk.CellRendererProgress()
|
||||
cpuUsageCol.pack_start(cpuUsage_txt, False)
|
||||
cpuUsageCol.pack_start(cpuUsage_img, False)
|
||||
cpuUsageCol.set_cell_data_func(cpuUsage_txt, self.cpu_usage_text, None)
|
||||
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)
|
||||
|
||||
memoryUsage_txt = gtk.CellRendererText()
|
||||
memoryUsage_img = gtk.CellRendererProgress()
|
||||
memoryUsageCol.pack_start(memoryUsage_txt, False)
|
||||
memoryUsageCol.pack_start(memoryUsage_img, False)
|
||||
memoryUsageCol.set_cell_data_func(memoryUsage_txt, self.memory_usage_text, None)
|
||||
memoryUsageCol.set_cell_data_func(memoryUsage_img, self.memory_usage_img, None)
|
||||
memoryUsageCol.set_visible(self.config.is_vmlist_memory_usage_visible())
|
||||
memoryUsageCol.set_sort_column_id(VMLIST_SORT_MEMORY_USAGE)
|
||||
|
||||
diskUsage_txt = gtk.CellRendererText()
|
||||
diskUsage_img = gtk.CellRendererProgress()
|
||||
diskUsageCol.pack_start(diskUsage_txt, False)
|
||||
diskUsageCol.pack_start(diskUsage_img, False)
|
||||
diskUsageCol.set_cell_data_func(diskUsage_txt, self.disk_usage_text, None)
|
||||
diskUsageCol.set_cell_data_func(diskUsage_img, self.disk_usage_img, None)
|
||||
diskUsageCol.set_visible(self.config.is_vmlist_disk_usage_visible())
|
||||
diskUsageCol.set_sort_column_id(VMLIST_SORT_DISK_USAGE)
|
||||
|
||||
networkTraffic_txt = gtk.CellRendererText()
|
||||
networkTraffic_img = gtk.CellRendererProgress()
|
||||
networkTrafficCol.pack_start(networkTraffic_txt, False)
|
||||
networkTrafficCol.pack_start(networkTraffic_img, False)
|
||||
networkTrafficCol.set_cell_data_func(networkTraffic_txt, self.network_traffic_text, None)
|
||||
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_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_USAGE, self.vmlist_disk_usage_sorter)
|
||||
model.set_sort_func(VMLIST_SORT_NETWORK_USAGE, self.vmlist_network_usage_sorter)
|
||||
|
||||
model.set_sort_column_id(VMLIST_SORT_NAME, gtk.SORT_ASCENDING)
|
||||
|
||||
|
||||
# XXX does python have a built-in sort op like perl's <=> / cmp ?
|
||||
def sort_op(self, a, b):
|
||||
if a > b:
|
||||
return 1
|
||||
elif a < b:
|
||||
return -1
|
||||
return 0
|
||||
|
||||
def vmlist_name_sorter(self, model, iter1, iter2):
|
||||
return self.sort_op(model.get_value(iter1, 0), model.get_value(iter2, 0))
|
||||
|
||||
def vmlist_cpu_usage_sorter(self, model, iter1, iter2):
|
||||
return self.sort_op(self.connection.get_stats().cpu_time(model.get_value(iter1, 0)), self.connection.get_stats().cpu_time(model.get_value(iter2, 0)))
|
||||
|
||||
def vmlist_memory_usage_sorter(self, model, iter1, iter2):
|
||||
return self.sort_op(self.connection.get_stats().current_memory(model.get_value(iter1, 0)), self.connection.get_stats().current_memory(model.get_value(iter2, 0)))
|
||||
|
||||
def vmlist_disk_usage_sorter(self, model, iter1, iter2):
|
||||
return self.sort_op(self.connection.get_stats().disk_usage(model.get_value(iter1, 0)), self.connection.get_stats().disk_usage(model.get_value(iter2, 0)))
|
||||
|
||||
def vmlist_network_usage_sorter(self, model, iter1, iter2):
|
||||
return self.sort_op(self.connection.get_stats().network_traffic(model.get_value(iter1, 0)), self.connection.get_stats().network_traffic(model.get_value(iter2, 0)))
|
||||
|
||||
def toggle_status_visible_conf(self, menu):
|
||||
self.config.set_vmlist_status_visible(menu.get_active())
|
||||
|
||||
def toggle_status_visible_widget(self, ignore1, ignore2, ignore3, ignore4):
|
||||
menu = self.window.get_widget("menu_view_status")
|
||||
vmlist = self.window.get_widget("vm-list")
|
||||
col = vmlist.get_column(1)
|
||||
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):
|
||||
menu = self.window.get_widget("menu_view_cpu_usage")
|
||||
vmlist = self.window.get_widget("vm-list")
|
||||
col = vmlist.get_column(2)
|
||||
col.set_visible(self.config.is_vmlist_cpu_usage_visible())
|
||||
|
||||
def toggle_memory_usage_visible_conf(self, menu):
|
||||
self.config.set_vmlist_memory_usage_visible(menu.get_active())
|
||||
|
||||
def toggle_memory_usage_visible_widget(self, ignore1, ignore2, ignore3, ignore4):
|
||||
menu = self.window.get_widget("menu_view_memory_usage")
|
||||
vmlist = self.window.get_widget("vm-list")
|
||||
col = vmlist.get_column(3)
|
||||
col.set_visible(self.config.is_vmlist_memory_usage_visible())
|
||||
|
||||
def toggle_disk_usage_visible_conf(self, menu):
|
||||
self.config.set_vmlist_disk_usage_visible(menu.get_active())
|
||||
|
||||
def toggle_disk_usage_visible_widget(self, ignore1, ignore2, ignore3, ignore4):
|
||||
menu = self.window.get_widget("menu_view_disk_usage")
|
||||
vmlist = self.window.get_widget("vm-list")
|
||||
col = vmlist.get_column(4)
|
||||
col.set_visible(self.config.is_vmlist_disk_usage_visible())
|
||||
|
||||
def toggle_network_traffic_visible_conf(self, menu):
|
||||
self.config.set_vmlist_network_traffic_visible(menu.get_active())
|
||||
|
||||
def toggle_network_traffic_visible_widget(self, ignore1, ignore2, ignore3, ignore4):
|
||||
menu = self.window.get_widget("menu_view_network_traffic")
|
||||
vmlist = self.window.get_widget("vm-list")
|
||||
col = vmlist.get_column(5)
|
||||
col.set_visible(self.config.is_vmlist_network_traffic_visible())
|
||||
|
||||
|
||||
def status_text(self, column, cell, model, iter, data):
|
||||
name = model.get_value(iter, 0)
|
||||
cell.set_property('text', self.connection.get_stats().run_status(name))
|
||||
|
||||
def status_icon(self, column, cell, model, iter, data):
|
||||
name = model.get_value(iter, 0)
|
||||
cell.set_property('pixbuf', self.connection.get_stats().run_status_icon(name))
|
||||
|
||||
def cpu_usage_text(self, column, cell, model, iter, data):
|
||||
name = model.get_value(iter, 0)
|
||||
cell.set_property('text', "%2.2f %%" % self.connection.get_stats().cpu_time_percentage(name))
|
||||
|
||||
def cpu_usage_img(self, column, cell, model, iter, data):
|
||||
name = model.get_value(iter, 0)
|
||||
cell.set_property('text', '')
|
||||
cell.set_property('value', self.connection.get_stats().cpu_time_percentage(name))
|
||||
|
||||
def memory_usage_text(self, column, cell, model, iter, data):
|
||||
name = model.get_value(iter, 0)
|
||||
current = self.connection.get_stats().current_memory(name)
|
||||
currentPercent = self.connection.get_stats().current_memory_percentage(name)
|
||||
cell.set_property('text', "%s (%2.2f%%)" % (self.pretty_mem(current) , currentPercent))
|
||||
|
||||
def memory_usage_img(self, column, cell, model, iter, data):
|
||||
name = model.get_value(iter, 0)
|
||||
currentPercent = self.connection.get_stats().current_memory_percentage(name)
|
||||
cell.set_property('text', '')
|
||||
cell.set_property('value', currentPercent)
|
||||
|
||||
def disk_usage_text(self, column, cell, model, iter, data):
|
||||
name = model.get_value(iter, 0)
|
||||
current = self.connection.get_stats().disk_usage(name)
|
||||
currentPercent = self.connection.get_stats().disk_usage_percentage(name)
|
||||
cell.set_property('text', "%s (%2.2f%%)" % (self.pretty_mem(current) , currentPercent))
|
||||
|
||||
def disk_usage_img(self, column, cell, model, iter, data):
|
||||
name = model.get_value(iter, 0)
|
||||
currentPercent = self.connection.get_stats().disk_usage_percentage(name)
|
||||
cell.set_property('text', '')
|
||||
cell.set_property('value', currentPercent)
|
||||
|
||||
def network_traffic_text(self, column, cell, model, iter, data):
|
||||
name = model.get_value(iter, 0)
|
||||
current = self.connection.get_stats().network_traffic(name)
|
||||
currentPercent = self.connection.get_stats().network_traffic_percentage(name)
|
||||
cell.set_property('text', "%s (%2.2f%%)" % (self.pretty_mem(current) , currentPercent))
|
||||
|
||||
def network_traffic_img(self, column, cell, model, iter, data):
|
||||
name = model.get_value(iter, 0)
|
||||
currentPercent = self.connection.get_stats().network_traffic_percentage(name)
|
||||
cell.set_property('text', '')
|
||||
cell.set_property('value', currentPercent)
|
||||
|
||||
# XXX or should we just always display MB ?
|
||||
def pretty_mem(self, mem):
|
||||
if mem > (1024*1024):
|
||||
return "%2.2f GB" % (mem/(1024.0*1024.0))
|
||||
else:
|
||||
return "%2.2f MB" % (mem/1024.0)
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
import gtk.glade
|
||||
|
||||
class vmmPreferences:
|
||||
def __init__(self, config):
|
||||
self.window = gtk.glade.XML(config.get_glade_file(), "vmm-preferences")
|
||||
self.config = config
|
||||
self.window.get_widget("vmm-preferences").hide()
|
||||
|
||||
self.config.on_stats_update_interval_changed(self.refresh_update_interval)
|
||||
self.config.on_stats_history_length_changed(self.refresh_history_length)
|
||||
|
||||
self.refresh_update_interval()
|
||||
self.refresh_history_length()
|
||||
|
||||
self.window.signal_autoconnect({
|
||||
"on_stats_update_interval_changed": self.change_update_interval,
|
||||
"on_stats_history_length_changed": self.change_history_length,
|
||||
|
||||
"on_close_clicked": self.close,
|
||||
"on_vmm_preferences_delete_event": self.close,
|
||||
})
|
||||
|
||||
def close(self,ignore1=None,ignore2=None):
|
||||
self.window.get_widget("vmm-preferences").hide()
|
||||
return 1
|
||||
|
||||
def show(self):
|
||||
win = self.window.get_widget("vmm-preferences")
|
||||
win.show_all()
|
||||
win.present()
|
||||
|
||||
def refresh_update_interval(self, ignore1=None,ignore2=None,ignore3=None,ignore4=None):
|
||||
self.window.get_widget("stats-update-interval").set_value(self.config.get_stats_update_interval())
|
||||
|
||||
def refresh_history_length(self, ignore1=None,ignore2=None,ignore3=None,ignore4=None):
|
||||
self.window.get_widget("stats-history-length").set_value(self.config.get_stats_history_length())
|
||||
|
||||
def change_update_interval(self, src):
|
||||
self.config.set_stats_update_interval(src.get_value_as_int())
|
||||
|
||||
def change_history_length(self, src):
|
||||
self.config.set_stats_history_length(src.get_value_as_int())
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
|
||||
import dbus.service
|
||||
|
||||
class vmmRemote(dbus.service.Object):
|
||||
def __init__(self, engine, bus_name, object_path="/com/redhat/virt/manager"):
|
||||
dbus.service.Object.__init__(self, bus_name, object_path)
|
||||
|
||||
self.engine = engine
|
||||
|
||||
@dbus.service.method("com.redhat.virt.manager", in_signature="s")
|
||||
def show_domain_creator(self, uri):
|
||||
# XXX fixme
|
||||
self.engine.show_manager(uri)
|
||||
|
||||
@dbus.service.method("com.redhat.virt.manager", in_signature="ss")
|
||||
def show_domain_editor(self, uri, uuid):
|
||||
self.engine.show_details(uri, uuid)
|
||||
|
||||
@dbus.service.method("com.redhat.virt.manager", in_signature="ss")
|
||||
def show_domain_performance(self, uri, uuid):
|
||||
self.engine.show_details(uri, uuid)
|
||||
|
||||
@dbus.service.method("com.redhat.virt.manager", in_signature="ss")
|
||||
def show_domain_console(self, uri, uuid):
|
||||
self.engine.show_console(uri, uuid)
|
||||
|
||||
@dbus.service.method("com.redhat.virt.manager", in_signature="s")
|
||||
def show_host_summary(self, uri):
|
||||
print "Openning manage " + uri
|
||||
self.engine.show_manager(uri)
|
||||
|
||||
@dbus.service.method("com.redhat.virt.manager")
|
||||
def show_open_connection(self):
|
||||
self.engine.show_open_connection()
|
|
@ -0,0 +1,202 @@
|
|||
|
||||
import libvirt
|
||||
import gtk.gdk
|
||||
from time import time
|
||||
|
||||
class vmmStats:
|
||||
def __init__(self, config, connection):
|
||||
self.config = config
|
||||
self.connection = connection
|
||||
self.record = {}
|
||||
|
||||
self.status_icons = {
|
||||
"blocked": gtk.gdk.pixbuf_new_from_file(config.get_icon_dir() + "/state_blocked.png"),
|
||||
"crashed": gtk.gdk.pixbuf_new_from_file(config.get_icon_dir() + "/state_crashed.png"),
|
||||
"paused": gtk.gdk.pixbuf_new_from_file(config.get_icon_dir() + "/state_paused.png"),
|
||||
"running": gtk.gdk.pixbuf_new_from_file(config.get_icon_dir() + "/state_running.png"),
|
||||
"shutdown": gtk.gdk.pixbuf_new_from_file(config.get_icon_dir() + "/state_shutdown.png"),
|
||||
"shutoff": gtk.gdk.pixbuf_new_from_file(config.get_icon_dir() + "/state_shutoff.png"),
|
||||
"idle": gtk.gdk.pixbuf_new_from_file(config.get_icon_dir() + "/state_idle.png"),
|
||||
}
|
||||
|
||||
self.hostinfo = self.connection.get_host_info()
|
||||
self.connection.connect_to_signal("vm_added", self._vm_added)
|
||||
self.connection.connect_to_signal("vm_removed", self._vm_removed)
|
||||
|
||||
|
||||
def _vm_added(self, vmuuid, name):
|
||||
self.record[vmuuid] = []
|
||||
|
||||
def _vm_removed(self, vmuuid):
|
||||
del self.record[vmuuid]
|
||||
|
||||
def update(self, vmuuid, vm):
|
||||
now = time()
|
||||
|
||||
self.hostinfo = self.connection.get_host_info()
|
||||
info = vm.info()
|
||||
|
||||
expected = self.config.get_stats_history_length()
|
||||
current = len(self.record[vmuuid])
|
||||
if current > expected:
|
||||
del self.record[vmuuid][expected:current]
|
||||
|
||||
prevCpuTime = 0
|
||||
prevTimestamp = 0
|
||||
if len(self.record[vmuuid]) > 0:
|
||||
prevTimestamp = self.record[vmuuid][0]["timestamp"]
|
||||
prevCpuTime = self.record[vmuuid][0]["cpuTimeAbs"]
|
||||
|
||||
pcentCpuTime = (info[4]-prevCpuTime) * 100 / ((now - prevTimestamp)*1000*1000*1000*self.host_active_processor_count())
|
||||
|
||||
pcentCurrMem = info[2] * 100 / self.host_memory_size()
|
||||
pcentMaxMem = info[1] * 100 / self.host_memory_size()
|
||||
|
||||
newStats = { "timestamp": now,
|
||||
"status": info[0],
|
||||
"cpuTime": (info[4]-prevCpuTime),
|
||||
"cpuTimeAbs": info[4],
|
||||
"cpuTimePercent": pcentCpuTime,
|
||||
"currMem": info[2],
|
||||
"currMemPercent": pcentCurrMem,
|
||||
"maxMem": info[1],
|
||||
"maxMemPercent": pcentMaxMem,
|
||||
}
|
||||
|
||||
self.record[vmuuid].insert(0, newStats)
|
||||
|
||||
nSamples = 5
|
||||
#nSamples = len(self.record[vmuuid])
|
||||
if nSamples > len(self.record[vmuuid]):
|
||||
nSamples = len(self.record[vmuuid])
|
||||
|
||||
startCpuTime = self.record[vmuuid][nSamples-1]["cpuTimeAbs"]
|
||||
startTimestamp = self.record[vmuuid][nSamples-1]["timestamp"]
|
||||
|
||||
if startTimestamp == now:
|
||||
self.record[vmuuid][0]["cpuTimeMovingAvg"] = self.record[vmuuid][0]["cpuTimeAbs"]
|
||||
self.record[vmuuid][0]["cpuTimeMovingAvgPercent"] = 0
|
||||
else:
|
||||
self.record[vmuuid][0]["cpuTimeMovingAvg"] = (self.record[vmuuid][0]["cpuTimeAbs"]-startCpuTime) / nSamples
|
||||
self.record[vmuuid][0]["cpuTimeMovingAvgPercent"] = (self.record[vmuuid][0]["cpuTimeAbs"]-startCpuTime) * 100 / ((now-startTimestamp)*1000*1000*1000 * self.host_active_processor_count())
|
||||
|
||||
|
||||
def current_memory(self, vmuuid):
|
||||
if len(self.record[vmuuid]) == 0:
|
||||
return 0
|
||||
return self.record[vmuuid][0]["currMem"]
|
||||
|
||||
def current_memory_percentage(self, vmuuid):
|
||||
if len(self.record[vmuuid]) == 0:
|
||||
return 0
|
||||
return self.record[vmuuid][0]["currMemPercent"]
|
||||
|
||||
def maximum_memory(self, vmuuid):
|
||||
if len(self.record[vmuuid]) == 0:
|
||||
return 0
|
||||
return self.record[vmuuid][0]["maxMem"]
|
||||
|
||||
def maximum_memory_percentage(self, vmuuid):
|
||||
if len(self.record[vmuuid]) == 0:
|
||||
return 0
|
||||
return self.record[vmuuid][0]["maxMemPercent"]
|
||||
|
||||
def cpu_time(self, vmuuid):
|
||||
if len(self.record[vmuuid]) == 0:
|
||||
return 0
|
||||
return self.record[vmuuid][0]["cpuTime"]
|
||||
|
||||
def cpu_time_percentage(self, vmuuid):
|
||||
if len(self.record[vmuuid]) == 0:
|
||||
return 0
|
||||
return self.record[vmuuid][0]["cpuTimePercent"]
|
||||
|
||||
def network_traffic(self, vmuuid):
|
||||
return 1
|
||||
|
||||
def network_traffic_percentage(self, vmuuid):
|
||||
return 1
|
||||
|
||||
def disk_usage(self, vmuuid):
|
||||
return 1
|
||||
|
||||
def disk_usage_percentage(self, vmuuid):
|
||||
return 1
|
||||
|
||||
def cpu_time_vector(self, vmuuid):
|
||||
vector = []
|
||||
stats = self.record[vmuuid]
|
||||
for i in range(self.config.get_stats_history_length()+1):
|
||||
if i < len(stats):
|
||||
vector.append(stats[i]["cpuTimePercent"])
|
||||
else:
|
||||
vector.append(0)
|
||||
return vector
|
||||
|
||||
def cpu_time_moving_avg_vector(self, vmuuid):
|
||||
vector = []
|
||||
stats = self.record[vmuuid]
|
||||
for i in range(self.config.get_stats_history_length()+1):
|
||||
if i < len(stats):
|
||||
vector.append(stats[i]["cpuTimeMovingAvgPercent"])
|
||||
else:
|
||||
vector.append(0)
|
||||
return vector
|
||||
|
||||
def current_memory_vector(self, vmuuid):
|
||||
vector = []
|
||||
stats = self.record[vmuuid]
|
||||
for i in range(self.config.get_stats_history_length()+1):
|
||||
if i < len(stats):
|
||||
vector.append(stats[i]["currMemPercent"])
|
||||
else:
|
||||
vector.append(0)
|
||||
return vector
|
||||
|
||||
def network_traffic_vector(self, vmuuid):
|
||||
vector = []
|
||||
stats = self.record[vmuuid]
|
||||
for i in range(self.config.get_stats_history_length()+1):
|
||||
vector.append(1)
|
||||
return vector
|
||||
|
||||
def disk_usage_vector(self, vmuuid):
|
||||
vector = []
|
||||
stats = self.record[vmuuid]
|
||||
for i in range(self.config.get_stats_history_length()+1):
|
||||
vector.append(1)
|
||||
return vector
|
||||
|
||||
def host_memory_size(self):
|
||||
return self.hostinfo[1]*1024
|
||||
|
||||
def host_active_processor_count(self):
|
||||
return self.hostinfo[2]
|
||||
|
||||
def host_maximum_processor_count(self):
|
||||
return self.hostinfo[4] * self.hostinfo[5] * self.hostinfo[6] * self.hostinfo[7]
|
||||
|
||||
def run_status(self, vmuuid):
|
||||
if len(self.record[vmuuid]) == 0:
|
||||
return "Shutoff"
|
||||
status = self.record[vmuuid][0]["status"]
|
||||
if status == libvirt.VIR_DOMAIN_NOSTATE:
|
||||
return "Idle"
|
||||
elif status == libvirt.VIR_DOMAIN_RUNNING:
|
||||
return "Running"
|
||||
elif status == libvirt.VIR_DOMAIN_BLOCKED:
|
||||
return "Blocked"
|
||||
elif status == libvirt.VIR_DOMAIN_PAUSED:
|
||||
return "Paused"
|
||||
elif status == libvirt.VIR_DOMAIN_SHUTDOWN:
|
||||
return "Shutdown"
|
||||
elif status == libvirt.VIR_DOMAIN_SHUTOFF:
|
||||
return "Shutoff"
|
||||
elif status == libvirt.VIR_DOMAIN_CRASHED:
|
||||
return "Crashed"
|
||||
else:
|
||||
raise "Unknown status code"
|
||||
|
||||
def run_status_icon(self, name):
|
||||
status = self.run_status(name)
|
||||
return self.status_icons[status.lower()]
|
Loading…
Reference in New Issue