Re-factored to avoid tight coupling between various windows/dialogs. Everything is now controlled/manager via vmmEngine

This commit is contained in:
Daniel P. Berrange 2006-06-14 16:20:06 -04:00
parent 29813b4368
commit 794dcd1e96
6 changed files with 175 additions and 102 deletions

View File

@ -3,19 +3,16 @@ import gobject
import libvirt
from virtManager.stats import vmmStats
from virtManager.manager import vmmManager
from virtManager.details import vmmDetails
from virtManager.console import vmmConsole
class vmmConnection(gobject.GObject):
__gsignals__ = {
"vm-added": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
(str, str,)),
(str, str, str,)),
"vm-removed": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
(str,)),
(str, str)),
"vm-updated": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
(str,)),
"disconnected": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (str,))
(str, str)),
"disconnected": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, [str])
}
def __init__(self, engine, config, uri, readOnly):
@ -42,16 +39,8 @@ class vmmConnection(gobject.GObject):
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_vm(self, uuid):
return self.vms[uuid]
def disconnect(self):
if self.vmm == None:
@ -69,32 +58,17 @@ class vmmConnection(gobject.GObject):
self.windowConsole[uuid].close()
del self.windowConsole[uuid]
self.emit("disconnected", "dummy")
self.emit("disconnected", self.uri)
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(self, name, callback):
gobject.GObject.connect(self, name, callback)
print "Cnnect " + name + " to " + str(callback)
if name == "vm-added":
for uuid in self.vms.keys():
self.emit("vm-added", uuid, self.vms[uuid].name())
self.emit("vm-added", self.uri, uuid, self.vms[uuid].name())
def tick(self):
if self.vmm == None:
@ -110,17 +84,17 @@ class vmmConnection(gobject.GObject):
for uuid in self.vms.keys():
if not(newVms.has_key(uuid)):
del self.vms[uuid]
self.emit("vm-removed", uuid)
self.emit("vm-removed", self.uri, uuid)
for uuid in newVms.keys():
if not(self.vms.has_key(uuid)):
self.vms[uuid] = newVms[uuid]
print "Trying to emit"
self.emit("vm-added",uuid, newVms[uuid].name())
self.emit("vm-added", self.uri, uuid, newVms[uuid].name())
for uuid in self.vms.keys():
self.stats.update(uuid, self.vms[uuid])
self.emit("vm-updated", uuid)
self.emit("vm-updated", self.uri, uuid)
return 1

View File

@ -1,12 +1,23 @@
import gobject
import gtk.glade
import libvirt
class vmmConsole:
def __init__(self, config, connection, vm, vmuuid):
class vmmConsole(gobject.GObject):
__gsignals__ = {
"action-show-details": (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, (str,str)),
"action-launch-terminal": (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, (str,str)),
"action-take-snapshot": (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, (str,str))
}
def __init__(self, config, hvuri, stats, vm, vmuuid):
self.__gobject_init__()
self.window = gtk.glade.XML(config.get_glade_file(), "vmm-console")
self.config = config
self.connection = connection
self.hvuri = hvuri
self.stats = stats
self.vm = vm
self.vmuuid = vmuuid
self.lastStatus = None
@ -43,8 +54,7 @@ class vmmConsole:
"on_control_details_clicked": self.control_vm_details,
})
self.connection.connect("vm-updated", self.vm_updated)
self.refresh_status()
self.refresh()
def show(self):
dialog = self.window.get_widget("vmm-console")
@ -83,19 +93,16 @@ class vmmConsole:
def control_vm_terminal(self, src):
return 0
self.emit("action-launch-terminal", self.hvuri, self.vmuuid)
def control_vm_snapshot(self, src):
return 0
self.emit("action-take-snapshot", self.hvuri, self.vmuuid)
def control_vm_details(self, src):
self.connection.show_details(self.vmuuid)
self.emit("action-show-details", self.hvuri, self.vmuuid)
def vm_updated(self, connection, uuid):
if uuid == self.vmuuid:
self.refresh_status()
def refresh_status(self):
def refresh(self):
print "In console refresh"
info = self.vm.info()
status = info[0]
@ -124,3 +131,4 @@ class vmmConsole:
self.lastStatus = status
gobject.type_register(vmmConsole)

View File

@ -1,4 +1,5 @@
import gobject
import gtk
import gtk.glade
@ -11,11 +12,21 @@ from matplotlib.backends.backend_gtk import FigureCanvasGTK, NavigationToolbar
from matplotlib.numerix import arange, sin, pi
class vmmDetails:
def __init__(self, config, connection, vm, vmuuid):
class vmmDetails(gobject.GObject):
__gsignals__ = {
"action-show-console": (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, (str,str)),
"action-launch-terminal": (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, (str,str)),
"action-take-snapshot": (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, (str,str))
}
def __init__(self, config, hvuri, stats, vm, vmuuid):
self.__gobject_init__()
self.window = gtk.glade.XML(config.get_glade_file(), "vmm-details")
self.config = config
self.connection = connection
self.hvuri = hvuri
self.stats = stats
self.vm = vm
self.vmuuid = vmuuid
self.lastStatus = None
@ -107,9 +118,8 @@ class vmmDetails:
"on_control_snapshot_clicked": self.control_vm_snapshot,
})
self.connection.connect("vm-updated", self.refresh_overview)
self.change_graph_ranges()
self.refresh_overview(self.connection, vmuuid)
self.refresh()
self.hw_selected()
def show(self):
@ -135,16 +145,16 @@ class vmmDetails:
return 0
def control_vm_shutdown(self, src):
if not(self.connection.get_stats().run_status(self.vmuuid) in [ "shutdown", "shutoff" ]):
if not(self.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" ]:
if self.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 self.stats.run_status(self.vmuuid) in [ "paused" ]:
if not src.get_active():
self.vm.resume()
else:
@ -157,10 +167,10 @@ class vmmDetails:
def control_vm_terminal(self, src):
return 0
self.emit("action-launch-terminal", self.hvuri, self.vmuuid)
def control_vm_snapshot(self, src):
return 0
self.emit("action-take-snapshot", self.hvuri, self.vmuuid)
def change_graph_ranges(self, ignore1=None,ignore2=None,ignore3=None,ignore4=None):
self.cpu_usage_graph.clear()
@ -207,22 +217,20 @@ class vmmDetails:
self.lastStatus = status
def refresh_overview(self, connection, vmuuid):
if not(vmuuid == self.vmuuid):
return
status = self.connection.get_stats().run_status(vmuuid)
def refresh(self):
print "In details refresh"
status = self.stats.run_status(self.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))
self.window.get_widget("overview-status-icon").set_from_pixbuf(self.stats.run_status_icon(self.vmuuid))
self.window.get_widget("overview-cpu-usage-text").set_text("%d %%" % self.stats.cpu_time_percentage(self.vmuuid))
self.window.get_widget("overview-memory-usage-text").set_text("%d MB of %d MB" % (self.stats.current_memory(self.vmuuid)/1024, self.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 = self.stats.cpu_time_vector(self.vmuuid)
cpu_vector.reverse()
cpu_vector_avg = self.connection.get_stats().cpu_time_moving_avg_vector(vmuuid)
cpu_vector_avg = self.stats.cpu_time_moving_avg_vector(self.vmuuid)
cpu_vector_avg.reverse()
if self.cpu_usage_line == None:
self.cpu_usage_line = self.cpu_usage_graph.plot(cpu_vector)
@ -239,7 +247,7 @@ class vmmDetails:
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 = self.stats.current_memory_vector(self.vmuuid)
memory_vector.reverse()
if self.memory_usage_line == None:
self.memory_usage_line = self.memory_usage_graph.plot(memory_vector)
@ -255,12 +263,13 @@ class vmmDetails:
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))
#self.network_traffic_line = self.network_traffic_graph.plot(self.stats.network_traffic_vector(self.vmuuid))
#else:
#self.network_traffic_line[0].set_ydata(self.connection.get_stats().network_traffic_vector(vmuuid))
#self.network_traffic_line[0].set_ydata(self.stats.network_traffic_vector(self.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()
gobject.type_register(vmmDetails)

View File

@ -1,14 +1,18 @@
import gobject
import gtk
import sys
from virtManager.about import vmmAbout
from virtManager.connect import vmmConnect
from virtManager.connection import vmmConnection
from virtManager.preferences import vmmPreferences
from virtManager.manager import vmmManager
from virtManager.details import vmmDetails
from virtManager.console import vmmConsole
class vmmEngine:
def __init__(self, config):
self.windowOpenConnection = None
self.windowConnect = None
self.windowPreferences = None
self.windowAbout = None
@ -24,11 +28,10 @@ class vmmEngine:
self.tick()
def _connection_disconnected(self, connection, dummy):
def _do_connection_disconnected(self, connection, hvuri):
del self.connections[connection.get_uri()]
if len(self.connections.keys()) == 0 and self.windowOpenConnection == None:
print "No more connections, getting out"
if len(self.connections.keys()) == 0 and self.windowConnect == None:
gtk.main_quit()
def _connect_to_uri(self, connect, uri, readOnly):
@ -42,6 +45,18 @@ class vmmEngine:
gtk.main_quit()
def _do_vm_updated(self, connection, hvuri, vmuuid):
for uuid in self.connections[hvuri]["windowDetails"].keys():
try:
self.connections[hvuri]["windowDetails"][uuid].refresh()
except:
pass
for uuid in self.connections[hvuri]["windowConsole"].keys():
try:
self.connections[hvuri]["windowConsole"][uuid].refresh()
except:
pass
def reschedule_timer(self, ignore1,ignore2,ignore3,ignore4):
self.schedule_timer()
@ -57,7 +72,7 @@ class vmmEngine:
def tick(self):
for uri in self.connections.keys():
try:
self.connections[uri].tick()
self.connections[uri]["connection"].tick()
except:
print str(sys.exc_info()[0]) + " " + str(sys.exc_info()[1])
print "Error refreshing connection " + uri
@ -70,6 +85,19 @@ class vmmEngine:
def get_config(self):
return self.config
def _do_show_about(self, src):
self.show_about()
def _do_show_preferences(self, src):
self.show_preferences()
def _do_show_connect(self, src):
self.show_connect()
def _do_show_manager(self, src, uri):
self.show_manager(uri)
def _do_show_details(self, src, uri, uuid):
self.show_details(uri, uuid)
def _do_show_console(self, src, uri, uuid):
self.show_console(uri, uuid)
def show_about(self):
if self.windowAbout == None:
self.windowAbout = vmmAbout(self.get_config())
@ -80,23 +108,52 @@ class vmmEngine:
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.connect("completed", self._connect_to_uri)
self.windowOpenConnection.show()
def show_connect(self):
if self.windowConnect == None:
self.windowConnect = vmmConnect(self.get_config(), self)
self.windowConnect.connect("completed", self._connect_to_uri)
self.windowConnect.show()
def show_console(self, uri, uuid):
con = self.get_connection(uri)
con.show_console(uuid)
if not(self.connections[uri]["windowConsole"].has_key(uuid)):
console = vmmConsole(self.get_config(),
uri,
con.get_stats(),
con.get_vm(uuid),
uuid)
console.connect("action-show-details", self._do_show_details)
self.connections[uri]["windowConsole"][uuid] = console
self.connections[uri]["windowConsole"][uuid].show()
def show_details(self, uri, uuid):
con = self.get_connection(uri)
con.show_details(uuid)
if not(self.connections[uri]["windowDetails"].has_key(uuid)):
details = vmmDetails(self.get_config(),
uri,
con.get_stats(),
con.get_vm(uuid),
uuid)
details.connect("action-show-console", self._do_show_console)
self.connections[uri]["windowDetails"][uuid] = details
self.connections[uri]["windowDetails"][uuid].show()
def show_manager(self, uri):
con = self.get_connection(uri)
con.show_manager()
if self.connections[uri]["windowManager"] == None:
manager = vmmManager(self.get_config(),
con,
uri)
manager.connect("action-show-console", self._do_show_console)
manager.connect("action-show-details", self._do_show_details)
manager.connect("action-show-preferences", self._do_show_preferences)
manager.connect("action-show-about", self._do_show_about)
manager.connect("action-show-connect", self._do_show_connect)
self.connections[uri]["windowManager"] = manager
self.connections[uri]["windowManager"].show()
def get_connection(self, uri, readOnly=True):
key = uri
@ -104,7 +161,14 @@ class vmmEngine:
key = "__default__"
if not(self.connections.has_key(key)):
self.connections[key] = vmmConnection(self, self.get_config(), uri, readOnly)
self.connections[key].connect("disconnected", self._connection_disconnected)
self.connections[key].tick()
return self.connections[key]
self.connections[key] = {
"connection": vmmConnection(self, self.get_config(), uri, readOnly),
"windowManager": None,
"windowDetails": {},
"windowConsole": {}
}
self.connections[key]["connection"].connect("disconnected", self._do_connection_disconnected)
self.connections[key]["connection"].connect("vm-updated", self._do_vm_updated)
self.connections[key]["connection"].tick()
return self.connections[key]["connection"]

View File

@ -1,4 +1,5 @@
import gobject
import gtk
import gtk.glade
@ -8,11 +9,25 @@ VMLIST_SORT_MEMORY_USAGE = 3
VMLIST_SORT_DISK_USAGE = 4
VMLIST_SORT_NETWORK_USAGE = 5
class vmmManager:
def __init__(self, config, connection):
class vmmManager(gobject.GObject):
__gsignals__ = {
"action-show-connect":(gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, []),
"action-show-console": (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, (str,str)),
"action-show-details": (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, (str,str)),
"action-show-about": (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, []),
"action-show-preferences": (gobject.SIGNAL_RUN_FIRST,
gobject.TYPE_NONE, []),
}
def __init__(self, config, connection, hvuri):
self.__gobject_init__()
self.window = gtk.glade.XML(config.get_glade_file(), "vmm-manager")
self.config = config
self.connection = connection
self.hvuri = hvuri
self.prepare_vmlist()
self.connection.connect("vm-added", self.vm_added)
@ -94,9 +109,9 @@ class vmmManager:
gtk.main_quit()
def open_connection(self, src=None):
self.connection.show_open_connection()
self.emit("action-show-connect");
def vm_added(self, connection, vmuuid, name):
def vm_added(self, connection, uri, vmuuid, name):
vmlist = self.window.get_widget("vm-list")
model = vmlist.get_model()
print "Added\n"
@ -110,7 +125,7 @@ class vmmManager:
model.append([vmuuid, name])
def vm_removed(self, connection, vmuuid):
def vm_removed(self, connection, uri, vmuuid):
vmlist = self.window.get_widget("vm-list")
model = vmlist.get_model()
@ -121,7 +136,7 @@ class vmmManager:
model.remove(model.iter_nth_child(None, row))
break
def vm_updated(self, connection, vmuuid):
def vm_updated(self, connection, uri, vmuuid):
vmlist = self.window.get_widget("vm-list")
model = vmlist.get_model()
@ -139,10 +154,12 @@ class vmmManager:
return None
def show_vm_details(self,ignore):
self.connection.show_details(self.current_vm())
print "Show detail"
self.emit("action-show-details", self.hvuri, self.current_vm())
def open_vm_console(self,ignore,ignore2=None,ignore3=None):
self.connection.show_console(self.current_vm())
print "Show console"
self.emit("action-show-console", self.hvuri, self.current_vm())
def vm_selected(self, selection):
@ -168,10 +185,10 @@ class vmmManager:
self.vmmenu.popup(None, None, None, 0, event.time)
def show_about(self, src):
self.connection.show_about()
self.emit("action-show-about")
def show_preferences(self, src):
self.connection.show_preferences()
self.emit("action-show-preferences")
def prepare_vmlist(self):
vmlist = self.window.get_widget("vm-list")
@ -383,3 +400,4 @@ class vmmManager:
else:
return "%2.2f MB" % (mem/1024.0)
gobject.type_register(vmmManager)

View File

@ -24,10 +24,10 @@ class vmmStats:
self.connection.connect("vm-removed", self._vm_removed)
def _vm_added(self, connection, vmuuid, name):
def _vm_added(self, connection, uri, vmuuid, name):
self.record[vmuuid] = []
def _vm_removed(self, connection, vmuuid):
def _vm_removed(self, connection, uri, vmuuid):
del self.record[vmuuid]
def update(self, vmuuid, vm):