details: Properly cleanup when VM/conn disappears

Make sure we are properly freeing all our state, so python can reap domains
and conn instances
This commit is contained in:
Cole Robinson 2011-04-11 18:35:21 -04:00
parent 87ebc2d46a
commit a52ad2eb37
8 changed files with 139 additions and 29 deletions

View File

@ -164,8 +164,26 @@ class vmmAddHardware(vmmGObjectUI):
def close(self, ignore1=None, ignore2=None):
self.topwin.hide()
self.remove_timers()
if self.storage_browser:
self.storage_browser.close()
return 1
def cleanup(self):
self.close()
vmmGObjectUI.cleanup(self)
try:
self.vm = None
self.conn = None
self._dev = None
if self.storage_browser:
self.storage_browser.cleanup()
self.storage_browser = None
except:
logging.exception("Error cleaning up addhw")
def remove_timers(self):
try:
if self.host_storage_timer:
@ -350,16 +368,16 @@ class vmmAddHardware(vmmGObjectUI):
_("Not supported for this guest type."),
"channel")
add_hw_option("USB Host Device", "system-run", PAGE_HOSTDEV,
self.vm.get_connection().is_nodedev_capable(),
self.conn.is_nodedev_capable(),
_("Connection does not support host device enumeration"),
"usb")
add_hw_option("PCI Host Device", "system-run", PAGE_HOSTDEV,
self.vm.get_connection().is_nodedev_capable(),
self.conn.is_nodedev_capable(),
_("Connection does not support host device enumeration"),
"pci")
add_hw_option("Video", "video-display", PAGE_VIDEO,
virtinst.support.check_conn_support(
self.vm.get_connection().vmm,
self.conn.vmm,
virtinst.support.SUPPORT_CONN_DOMAIN_VIDEO),
_("Libvirt version does not support video devices."))
add_hw_option("Watchdog", "device_pci", PAGE_WATCHDOG,
@ -388,16 +406,16 @@ class vmmAddHardware(vmmGObjectUI):
target_list.set_active(0)
# Network init
newmac = uihelpers.generate_macaddr(self.vm.get_connection())
newmac = uihelpers.generate_macaddr(self.conn)
self.window.get_widget("mac-address").set_active(bool(newmac))
self.window.get_widget("create-mac-address").set_text(newmac)
self.change_macaddr_use()
net_list = self.window.get_widget("net-list")
net_warn = self.window.get_widget("net-list-warn")
uihelpers.populate_network_list(net_list, self.vm.get_connection())
uihelpers.populate_network_list(net_list, self.conn)
error = self.vm.get_connection().netdev_error
error = self.conn.netdev_error
if error:
net_warn.show()
util.tooltip_wrapper(net_warn, error)
@ -473,7 +491,7 @@ class vmmAddHardware(vmmGObjectUI):
add_dev("usb", virtinst.VirtualDisk.DEVICE_DISK, "USB disk")
if self.vm.get_hv_type() == "kvm":
add_dev("virtio", virtinst.VirtualDisk.DEVICE_DISK, "Virtio Disk")
if self.vm.get_connection().is_xen():
if self.conn.is_xen():
add_dev("xen", virtinst.VirtualDisk.DEVICE_DISK, "Virtual disk")
def populate_input_model(self, model):
@ -497,9 +515,9 @@ class vmmAddHardware(vmmGObjectUI):
subdevs = []
if subtype:
subdevs = self.vm.get_connection().get_nodedevs(subtype, subcap)
subdevs = self.conn.get_nodedevs(subtype, subcap)
devs = self.vm.get_connection().get_nodedevs(devtype, devcap)
devs = self.conn.get_nodedevs(devtype, devcap)
for dev in devs:
prettyname = dev.pretty_name()
@ -865,7 +883,7 @@ class vmmAddHardware(vmmGObjectUI):
chartype = self.get_char_type()
devtype = src.get_model()[src.get_active()][0]
conn = self.vm.get_connection().vmm
conn = self.conn.vmm
self._dev = VirtualCharDevice.get_dev_instance(conn,
chartype,
@ -1100,7 +1118,7 @@ class vmmAddHardware(vmmGObjectUI):
return self.err.val_err(_("Invalid MAC address"),
_("A MAC address must be entered."))
ret = uihelpers.validate_network(self.topwin, self.vm.get_connection(),
ret = uihelpers.validate_network(self.topwin, self.conn,
nettype, devname, mac, model)
if ret == False:
return False
@ -1122,7 +1140,7 @@ class vmmAddHardware(vmmGObjectUI):
"sdl": virtinst.VirtualGraphics.TYPE_SDL}[graphics]
self._dev = virtinst.VirtualGraphics(type=_type,
conn=self.vm.get_connection().vmm)
conn=self.conn.vmm)
try:
self._dev.port = self.get_config_graphics_port()
self._dev.tlsPort = self.get_config_graphics_tls_port()
@ -1150,7 +1168,7 @@ class vmmAddHardware(vmmGObjectUI):
try:
self._dev = virtinst.VirtualHostDevice.device_from_node(
conn=self.vm.get_connection().vmm,
conn=self.conn.vmm,
name=nodedev_name)
except Exception, e:
return self.err.val_err(_("Host device parameter error"), str(e))
@ -1159,7 +1177,7 @@ class vmmAddHardware(vmmGObjectUI):
chartype = self.get_char_type()
devbox = self.window.get_widget("char-device-type")
devtype = devbox.get_model()[devbox.get_active()][0]
conn = self.vm.get_connection().vmm
conn = self.conn.vmm
devclass = VirtualCharDevice.get_dev_instance(conn, chartype, devtype)
@ -1199,7 +1217,7 @@ class vmmAddHardware(vmmGObjectUI):
chartype.capitalize(), str(e))
def validate_page_video(self):
conn = self.vm.get_connection().vmm
conn = self.conn.vmm
model = self.get_config_video_model()
try:
@ -1210,7 +1228,7 @@ class vmmAddHardware(vmmGObjectUI):
str(e))
def validate_page_watchdog(self):
conn = self.vm.get_connection().vmm
conn = self.conn.vmm
model = self.get_config_watchdog_model()
action = self.get_config_watchdog_action()
@ -1233,7 +1251,7 @@ class vmmAddHardware(vmmGObjectUI):
if path:
textent.set_text(path)
conn = self.vm.get_connection()
conn = self.conn
if self.storage_browser == None:
self.storage_browser = vmmStorageBrowser(conn)

View File

@ -119,6 +119,7 @@ class vmmGObjectUI(vmmGObject):
def cleanup(self):
vmmGObject.cleanup(self)
self.window = None
self.topwin.destroy()
self.topwin = None
self.gladefile = None
self.err = None

View File

@ -17,6 +17,9 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA.
#
import logging
import gobject
import virtManager.uihelpers as uihelpers
@ -48,7 +51,7 @@ class vmmChooseCD(vmmGObjectUI):
"on_ok_clicked": self.ok,
"on_vmm_choose_cd_delete_event": self.close,
"on_cancel_clicked": self.close,
})
})
self.window.get_widget("iso-image").set_active(True)
@ -57,12 +60,30 @@ class vmmChooseCD(vmmGObjectUI):
def close(self, ignore1=None, ignore2=None):
self.topwin.hide()
if self.storage_browser:
self.storage_browser.close()
return 1
def show(self):
self.reset_state()
self.topwin.show()
def cleanup(self):
self.close()
try:
self.conn = None
self.dev_id_info = None
if self.storage_browser:
self.storage_browser.cleanup()
self.storage_browser = None
except:
logging.exception("Error cleaning up choosecd")
vmmGObjectUI.cleanup(self)
def reset_state(self):
cd_path = self.window.get_widget("cd-path")
use_cdrom = (cd_path.get_active() > -1)

View File

@ -534,6 +534,10 @@ class vmmConsolePages(vmmGObjectUI):
return 1
return 0
def cleanup(self):
vmmGObjectUI.cleanup(self)
self.vm = None
##########################
# Initialization helpers #
##########################

View File

@ -84,6 +84,16 @@ class vmmCreateVolume(vmmGObjectUI):
self.set_modal(False)
return 1
def cleanup(self):
self.close()
vmmGObjectUI.cleanup(self)
try:
self.conn = None
self.parent_pool = None
except:
logging.exception("Error cleaning up addvol")
def set_name_hint(self, hint):
self.name_hint = hint

View File

@ -454,6 +454,37 @@ class vmmDetails(vmmGObjectUI):
self.hw_selected()
self.refresh_vm_state()
def cleanup(self):
self.close()
try:
self.vm = None
self.conn = None
self.engine = None
self.addhwmenu = None
self.console.cleanup()
self.console = None
if self.addhw:
self.addhw.cleanup()
self.addhw = None
if self.storage_browser:
self.storage_browser.cleanup()
self.storage_browser = None
for key in self.media_choosers:
if self.media_choosers[key]:
self.media_choosers[key].cleanup()
self.media_choosers = {}
for name in self.serial_tabs:
self._close_serial_tab(name)
except:
logging.exception("Error cleaning up details")
vmmGObjectUI.cleanup(self)
def show(self):
vis = self.is_visible()

View File

@ -376,23 +376,29 @@ class vmmEngine(vmmGObject):
def _do_vm_removed(self, connection, hvuri, vmuuid):
ignore = connection
if vmuuid in self.connections[hvuri]["windowDetails"]:
self.connections[hvuri]["windowDetails"][vmuuid].close()
del self.connections[hvuri]["windowDetails"][vmuuid]
if vmuuid not in self.connections[hvuri]["windowDetails"]:
return
self.connections[hvuri]["windowDetails"][vmuuid].cleanup()
del(self.connections[hvuri]["windowDetails"][vmuuid])
def _do_connection_changed(self, connection):
if connection.get_state() == connection.STATE_ACTIVE or \
connection.get_state() == connection.STATE_CONNECTING:
if (connection.get_state() == connection.STATE_ACTIVE or
connection.get_state() == connection.STATE_CONNECTING):
return
hvuri = connection.get_uri()
for vmuuid in self.connections[hvuri]["windowDetails"].keys():
self.connections[hvuri]["windowDetails"][vmuuid].close()
del self.connections[hvuri]["windowDetails"][vmuuid]
self.connections[hvuri]["windowDetails"][vmuuid].cleanup()
del(self.connections[hvuri]["windowDetails"][vmuuid])
if self.connections[hvuri]["windowHost"] is not None:
self.connections[hvuri]["windowHost"].close()
self.connections[hvuri]["windowHost"] = None
if (self.windowCreate and self.windowCreate.conn and
if (self.windowCreate and
self.windowCreate.conn and
self.windowCreate.conn.get_uri() == hvuri):
self.windowCreate.close()

View File

@ -86,6 +86,27 @@ class vmmStorageBrowser(vmmGObjectUI):
self.addvol.close()
return 1
def cleanup(self):
self.close()
vmmGObjectUI.cleanup(self)
try:
self.remove_conn()
self.conn = None
if self.addvol:
self.addvol.cleanup()
self.addvol = None
except:
logging.exception("Error cleaning up storagebrowse")
def remove_conn(self):
if not self.conn:
return
for i in self.conn_signal_ids:
self.conn.disconnect(i)
def set_finish_cb(self, callback):
if self.finish_cb_id:
self.disconnect(self.finish_cb_id)
@ -140,11 +161,9 @@ class vmmStorageBrowser(vmmGObjectUI):
volListModel.set_sort_column_id(1, gtk.SORT_ASCENDING)
def reset_state(self, conn=None):
if conn and conn != self.conn:
for i in self.conn_signal_ids:
self.conn.disconnect(i)
self.remove_conn()
self.conn = conn
pool_list = self.window.get_widget("pool-list")