From a3f8d73a9c3a670e1c48b16f67e48e429c07e18a Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Thu, 9 Apr 2015 18:02:42 -0400 Subject: [PATCH] libvirtobject: Unify internal status APIs and signals Drop config-changes vs. status-changed and just use one signal, since they are largely the same code paths for all users. --- virtManager/connection.py | 4 ++ virtManager/console.py | 2 +- virtManager/create.py | 4 +- virtManager/details.py | 3 +- virtManager/domain.py | 76 ++++++++++------------------------ virtManager/host.py | 4 +- virtManager/interface.py | 53 ++++++++++-------------- virtManager/libvirtobject.py | 79 +++++++++++++++++++++++++++++++----- virtManager/manager.py | 27 +++--------- virtManager/network.py | 65 ++++++++--------------------- virtManager/nodedev.py | 4 ++ virtManager/serialcon.py | 2 +- virtManager/storagelist.py | 2 +- virtManager/storagepool.py | 70 +++++++++++++------------------- virtManager/systray.py | 2 +- 15 files changed, 181 insertions(+), 216 deletions(-) diff --git a/virtManager/connection.py b/virtManager/connection.py index 4368089d1..691e3f38e 100644 --- a/virtManager/connection.py +++ b/virtManager/connection.py @@ -678,6 +678,8 @@ class vmmConnection(vmmGObject): obj = self._vms.get(domain.name(), None) if not obj: return + + # Uses forcesignal=True self.idle_add(obj.refresh_xml, True) def _domain_lifecycle_event(self, conn, domain, event, reason, userdata): @@ -692,6 +694,7 @@ class vmmConnection(vmmGObject): self.idle_add(obj.force_update_status, True) if event == libvirt.VIR_DOMAIN_EVENT_DEFINED: + # Uses forcesignal=True self.idle_add(obj.refresh_xml, True) else: self.schedule_priority_tick(pollvm=True, force=True) @@ -706,6 +709,7 @@ class vmmConnection(vmmGObject): self.idle_add(obj.force_update_status, True) if event == getattr(libvirt, "VIR_NETWORK_EVENT_DEFINED", 0): + # Uses forcesignal=True self.idle_add(obj.refresh_xml, True) else: self.schedule_priority_tick(pollnet=True, force=True) diff --git a/virtManager/console.py b/virtManager/console.py index fae1c99f1..3abb0a417 100644 --- a/virtManager/console.py +++ b/virtManager/console.py @@ -51,7 +51,7 @@ class vmmConsolePages(vmmGObjectUI): self.vm = vm self._pointer_is_grabbed = False self._change_title() - self.vm.connect("config-changed", self._change_title) + self.vm.connect("state-changed", self._change_title) self._force_resize = False # State for disabling modifiers when keyboard is grabbed diff --git a/virtManager/create.py b/virtManager/create.py index ad3fb4f26..679b68558 100644 --- a/virtManager/create.py +++ b/virtManager/create.py @@ -1891,7 +1891,7 @@ class vmmCreate(vmmGObjectUI): # Register a status listener, which will restart the # guest after the install has finished def cb(): - vm.connect_opt_out("status-changed", + vm.connect_opt_out("state-changed", self.check_install_status, guest) return False self.idle_add(cb) @@ -1925,7 +1925,7 @@ class vmmCreate(vmmGObjectUI): # will force one final restart. virtinst_guest.continue_install() - vm.connect_opt_out("status-changed", + vm.connect_opt_out("state-changed", self.check_install_status, None) return True diff --git a/virtManager/details.py b/virtManager/details.py index 0b6e2349d..6ace2f5d6 100644 --- a/virtManager/details.py +++ b/virtManager/details.py @@ -574,8 +574,7 @@ class vmmDetails(vmmGObjectUI): }) # Deliberately keep all this after signal connection - self.vm.connect("status-changed", self.refresh_vm_state) - self.vm.connect("config-changed", self.refresh_vm_state) + self.vm.connect("state-changed", self.refresh_vm_state) self.vm.connect("resources-sampled", self.refresh_resources) self.populate_hw_list() diff --git a/virtManager/domain.py b/virtManager/domain.py index 53cd79fc2..7fb731d27 100644 --- a/virtManager/domain.py +++ b/virtManager/domain.py @@ -177,6 +177,8 @@ class vmmDomainSnapshot(vmmLibvirtObject): def _XMLDesc(self, flags): return self._backend.getXMLDesc(flags=flags) + def _get_backend_status(self): + return self._STATUS_ACTIVE def delete(self, force=True): ignore = force @@ -214,6 +216,8 @@ class vmmDomain(vmmLibvirtObject): "pre-startup": (GObject.SignalFlags.RUN_FIRST, None, [object]), } + _conn_tick_poll_param = "pollvm" + @staticmethod def pretty_run_status(status, has_saved=False): if status == libvirt.VIR_DOMAIN_RUNNING: @@ -302,10 +306,7 @@ class vmmDomain(vmmLibvirtObject): self._snapshot_list = None self._autostart = None self._domain_caps = None - - self.lastStatus = libvirt.VIR_DOMAIN_SHUTOFF - self._lastStatusReason = getattr(libvirt, "VIR_DOMAIN_SHUTOFF_SHUTDOWN", - 1) + self._status_reason = None self.managedsave_supported = False self.remote_console_supported = False @@ -362,7 +363,7 @@ class vmmDomain(vmmLibvirtObject): self.toggle_sample_mem_stats() self.toggle_sample_cpu_stats() - self.force_update_status(from_event=True, log=False) + self.force_update_status(from_event=True) # Prime caches self.refresh_xml() @@ -426,10 +427,14 @@ class vmmDomain(vmmLibvirtObject): return self._id def status(self): - return self.lastStatus + return self._normalize_status(self._get_status()) def status_reason(self): - return self._lastStatusReason + if self._status_reason is None: + self._status_reason = 1 + if self.domain_state_supported: + self._status_reason = self._backend.state()[1] + return self._status_reason def get_cloning(self): return self.cloning @@ -520,6 +525,9 @@ class vmmDomain(vmmLibvirtObject): def _invalidate_xml(self): vmmLibvirtObject._invalidate_xml(self) self._id = None + self._has_managed_save = None + self._status_reason = None + self._has_managed_save = None def _lookup_device_to_define(self, origdev, guest=None): if guest is None: @@ -1034,6 +1042,8 @@ class vmmDomain(vmmLibvirtObject): self.conn.define_domain(newxml) def _XMLDesc(self, flags): return self._backend.XMLDesc(flags) + def _get_backend_status(self): + return self._backend.info()[0] def get_autostart(self): if self._autostart is None: @@ -1345,7 +1355,7 @@ class vmmDomain(vmmLibvirtObject): self.shutdown() def add_reboot(): - self.reboot_listener = self.connect_opt_out("status-changed", + self.reboot_listener = self.connect_opt_out("state-changed", reboot_listener, self) self.idle_add(add_reboot) @@ -1716,48 +1726,6 @@ class vmmDomain(vmmLibvirtObject): status = libvirt.VIR_DOMAIN_NOSTATE return vm_status_icons[status] - def force_update_status(self, from_event=False, log=True): - """ - Fetch current domain state and clear status cache - """ - if not from_event and self._using_events(): - return - - try: - info = self._backend.info() - if log: - logging.debug("domain=%s status changed to %d=%s", - self.get_name(), info[0], self.pretty_run_status(info[0])) - - self._update_status(info[0]) - except libvirt.libvirtError, e: - # Transient domain might have disappeared, tell the connection - # to update the domain list - logging.debug("Error setting domain status: %s\nDomain might " - "have disappeared, triggering connection tick", e) - self.conn.schedule_priority_tick(pollvm=True, force=True) - - def _update_status(self, status): - """ - Internal helper to change cached status to 'status' and signal - clients if we actually changed state - """ - status = self._normalize_status(status) - - if status == self.lastStatus: - return - - self.lastStatus = status - if self.domain_state_supported: - self._lastStatusReason = self._backend.state()[1] - self._has_managed_save = None - - # Send 'config-changed' before a status-update, so users - # are operating with fresh XML - self.refresh_xml() - - self.idle_emit("status-changed") - def inspection_data_updated(self): self.idle_emit("inspection-changed") @@ -1934,8 +1902,8 @@ class vmmDomain(vmmLibvirtObject): if stats_update: self._tick_stats(info) - if not self._using_events(): - self._update_status(info[0]) + # This is a no-op if using events + self.force_update_status(newstatus=info[0]) if stats_update: self.idle_emit("resources-sampled") @@ -2015,7 +1983,7 @@ class vmmDomainVirtinst(vmmDomain): return self._backend.autostart def set_autostart(self, val): self._backend.autostart = bool(val) - self.emit("config-changed") + self.emit("state-changed") def _using_events(self): return False @@ -2038,7 +2006,7 @@ class vmmDomainVirtinst(vmmDomain): def _define(self, newxml): ignore = newxml - self.emit("config-changed") + self.emit("state-changed") def _invalidate_xml(self): vmmDomain._invalidate_xml(self) diff --git a/virtManager/host.py b/virtManager/host.py index 45225d1f9..085354e1e 100644 --- a/virtManager/host.py +++ b/virtManager/host.py @@ -703,7 +703,7 @@ class vmmHost(vmmGObjectUI): net.disconnect_by_func(self.refresh_network) except: pass - net.connect("status-changed", self.refresh_network) + net.connect("state-changed", self.refresh_network) model.append([net.get_connkey(), net.get_name(), "network-idle", Gtk.IconSize.LARGE_TOOLBAR, bool(net.is_active())]) @@ -955,7 +955,7 @@ class vmmHost(vmmGObjectUI): iface.disconnect_by_func(self.refresh_interface) except: pass - iface.connect("status-changed", self.refresh_interface) + iface.connect("state-changed", self.refresh_interface) model.append([iface.get_connkey(), iface.get_name(), "network-idle", Gtk.IconSize.LARGE_TOOLBAR, bool(iface.is_active())]) diff --git a/virtManager/interface.py b/virtManager/interface.py index 55b8b0ced..cd91283b8 100644 --- a/virtManager/interface.py +++ b/virtManager/interface.py @@ -24,16 +24,14 @@ from .libvirtobject import vmmLibvirtObject class vmmInterface(vmmLibvirtObject): + _conn_tick_poll_param = "polliface" + def __init__(self, conn, backend, key): vmmLibvirtObject.__init__(self, conn, backend, key, Interface) - self._active = True - (self._inactive_xml_flags, self._active_xml_flags) = self.conn.get_interface_flags(self._backend) - self._support_isactive = None - self.tick() # Routines from vmmLibvirtObject @@ -41,36 +39,21 @@ class vmmInterface(vmmLibvirtObject): return self._backend.XMLDesc(flags) def _define(self, xml): return self.conn.define_interface(xml) - - def _set_active(self, state): - if state == self._active: - return - - self._active = state - self._invalidate_xml() - self.idle_emit("status-changed") - - def _backend_get_active(self): - ret = True - if self._support_isactive is None: - self._support_isactive = self.conn.check_support( - self.conn.SUPPORT_INTERFACE_ISACTIVE, self._backend) - - if not self._support_isactive: - return True - return bool(self._backend.isActive()) - - def tick(self): - self._set_active(self._backend_get_active()) - - def is_active(self): - return self._active - - def get_mac(self): - return self.get_xmlobj().macaddr + def _check_supports_isactive(self): + return self.conn.check_support( + self.conn.SUPPORT_INTERFACE_ISACTIVE, self._backend) + def _get_backend_status(self): + return self._backend_get_active() def _kick_conn(self): self.conn.schedule_priority_tick(polliface=True) + def tick(self): + self.force_update_status() + + + ##################### + # Object operations # + ##################### def start(self): self._backend.create(0) @@ -87,6 +70,14 @@ class vmmInterface(vmmLibvirtObject): self._backend.undefine() self._kick_conn() + + ################ + # XML routines # + ################ + + def get_mac(self): + return self.get_xmlobj().macaddr + def is_bridge(self): typ = self.get_type() return typ == "bridge" diff --git a/virtManager/libvirtobject.py b/virtManager/libvirtobject.py index 24781caa5..06f73625d 100644 --- a/virtManager/libvirtobject.py +++ b/virtManager/libvirtobject.py @@ -27,12 +27,18 @@ from .baseclass import vmmGObject class vmmLibvirtObject(vmmGObject): __gsignals__ = { - "status-changed": (GObject.SignalFlags.RUN_FIRST, None, []), - "config-changed": (GObject.SignalFlags.RUN_FIRST, None, []), + "state-changed": (GObject.SignalFlags.RUN_FIRST, None, []), "started": (GObject.SignalFlags.RUN_FIRST, None, []), "stopped": (GObject.SignalFlags.RUN_FIRST, None, []), } + _STATUS_ACTIVE = 1 + _STATUS_INACTIVE = 2 + + # The parameter name for conn.tick() object polling. So + # for vmmDomain == "pollvm" + _conn_tick_poll_param = None + def __init__(self, conn, backend, key, parseclass): vmmGObject.__init__(self) self._conn = conn @@ -40,6 +46,9 @@ class vmmLibvirtObject(vmmGObject): self._key = key self._parseclass = parseclass + self.__status = self._STATUS_ACTIVE + self._support_isactive = None + self._xmlobj = None self._xmlobj_to_define = None self._is_xml_valid = False @@ -52,6 +61,7 @@ class vmmLibvirtObject(vmmGObject): self._name = None self.get_name() + @staticmethod def log_redefine_xml_diff(obj, origxml, newxml): objname = "<%s name=%s>" % (obj.__class__.__name__, obj.get_name()) @@ -105,7 +115,7 @@ class vmmLibvirtObject(vmmGObject): finally: self._invalidate_xml() - self.emit("config-changed") + self.emit("state-changed") ############################################################# @@ -116,6 +126,10 @@ class vmmLibvirtObject(vmmGObject): raise NotImplementedError() def _using_events(self): return False + def _check_supports_isactive(self): + return False + def _get_backend_status(self): + raise NotImplementedError() def _define(self, xml): ignore = xml @@ -124,10 +138,6 @@ class vmmLibvirtObject(vmmGObject): def delete(self, force=True): ignore = force - def force_update_status(self, from_event=False, log=True): - ignore = from_event - ignore = log - def get_name(self): if self._name is None: self._name = self._backend_get_name() @@ -137,16 +147,65 @@ class vmmLibvirtObject(vmmGObject): return self._backend.name() + ################### + # Status handling # + ################### + + def _get_status(self): + return self.__status + + def is_active(self): + # vmmDomain overwrites this since it has more fine grained statuses + return self._get_status() == self._STATUS_ACTIVE + + def force_update_status(self, from_event=False, newstatus=None): + """ + :param newstatus: Used by vmmDomain as a small optimization to + avoid polling info() twice + """ + if self._using_events() and not from_event: + return + + try: + status = newstatus + if newstatus is None: + status = self._get_backend_status() + if status == self.__status: + return + self.__status = status + + # This will send state-change for us + self.refresh_xml(forcesignal=True) + except: + # If we hit an exception here, it's often that the object + # disappeared, so request the poll loop to be updated + if self._conn_tick_poll_param: + logging.debug("force_update_status: Triggering %s " + "list refresh", self.__class__) + kwargs = {"force": True, self._conn_tick_poll_param: True} + self.conn.schedule_priority_tick(**kwargs) + + def _backend_get_active(self): + if self._support_isactive is None: + self._support_isactive = self._check_supports_isactive() + + if not self._support_isactive: + return self._STATUS_ACTIVE + return (bool(self._backend.isActive()) and + self._STATUS_ACTIVE or + self._STATUS_INACTIVE) + + ################## # Public XML API # ################## def refresh_xml(self, forcesignal=False): """ - Force an xml update. Signal 'config-changed' if domain xml has + Force an xml update. Signal 'state-changed' if domain xml has changed since last refresh - :param forcesignal: Send config-changed unconditionally + :param forcesignal: Send state-changed unconditionally """ origxml = None if self._xmlobj: @@ -159,7 +218,7 @@ class vmmLibvirtObject(vmmGObject): self._is_xml_valid = True if forcesignal or origxml != active_xml: - self.idle_emit("config-changed") + self.idle_emit("state-changed") def get_xmlobj(self, inactive=False, refresh_if_nec=True): """ diff --git a/virtManager/manager.py b/virtManager/manager.py index 619b2b0ae..05512b2d2 100644 --- a/virtManager/manager.py +++ b/virtManager/manager.py @@ -588,8 +588,7 @@ class vmmManager(vmmGObjectUI): if self.vm_row_key(vm) in self.rows: return - vm.connect("config-changed", self.vm_config_changed) - vm.connect("status-changed", self.vm_status_changed) + vm.connect("state-changed", self.vm_changed) vm.connect("resources-sampled", self.vm_row_updated) vm.connect("inspection-changed", self.vm_inspection_changed) @@ -778,12 +777,15 @@ class vmmManager(vmmGObjectUI): return self.widget("vm-list").get_model().row_changed(row.path, row.iter) - def vm_config_changed(self, vm): + def vm_changed(self, vm): row = self.rows.get(self.vm_row_key(vm), None) if row is None: return try: + if vm == self.current_vm(): + self.update_current_selection() + name = vm.get_name_or_title() status = vm.run_status() @@ -803,25 +805,6 @@ class vmmManager(vmmGObjectUI): self.vm_row_updated(vm) - def vm_status_changed(self, vm): - parent = self.rows[vm.conn.get_uri()].iter - vmlist = self.widget("vm-list") - model = vmlist.get_model() - - missing = True - for row in range(model.iter_n_children(parent)): - _iter = model.iter_nth_child(parent, row) - if model[_iter][ROW_HANDLE] == vm: - missing = False - break - - if missing: - self._append_vm(model, vm, vm.conn) - - # Update run/shutdown/pause button states - self.update_current_selection() - self.vm_config_changed(vm) - def vm_inspection_changed(self, vm): row = self.rows.get(self.vm_row_key(vm), None) if row is None: diff --git a/virtManager/network.py b/virtManager/network.py index 233e4e8fb..d484f995d 100644 --- a/virtManager/network.py +++ b/virtManager/network.py @@ -18,8 +18,6 @@ # MA 02110-1301 USA. # -import logging - import ipaddr from virtinst import Network @@ -41,11 +39,10 @@ def _make_addr_str(addrStr, prefix, netmaskStr): class vmmNetwork(vmmLibvirtObject): + _conn_tick_poll_param = "pollnet" + def __init__(self, conn, backend, key): vmmLibvirtObject.__init__(self, conn, backend, key, Network) - self._active = True - - self._support_isactive = None self.force_update_status(from_event=True) @@ -60,47 +57,22 @@ class vmmNetwork(vmmLibvirtObject): return self.conn.define_network(xml) def _using_events(self): return self.conn.using_network_events + def _check_supports_isactive(self): + return self.conn.check_support( + self.conn.SUPPORT_NET_ISACTIVE, self._backend) + def _get_backend_status(self): + return self._backend_get_active() + + def _kick_conn(self): + self.conn.schedule_priority_tick(pollnet=True) + def tick(self): + self.force_update_status() ########### # Actions # ########### - def _backend_get_active(self): - if self._support_isactive is None: - self._support_isactive = self.conn.check_support( - self.conn.SUPPORT_NET_ISACTIVE, self._backend) - - if not self._support_isactive: - return True - return bool(self._backend.isActive()) - - def _set_active(self, state): - if state == self._active: - return - - self._active = state - self._invalidate_xml() - self.idle_emit("status-changed") - - def force_update_status(self, from_event=False, log=True): - ignore = log - if self._using_events() and not from_event: - return - - try: - self._set_active(self._backend_get_active()) - except: - logging.debug("force_update_status: Triggering network " - "list refresh") - self.conn.schedule_priority_tick(pollnet=True, force=True) - - def is_active(self): - return self._active - - def _kick_conn(self): - self.conn.schedule_priority_tick(pollnet=True) - def start(self): self._backend.create() self._kick_conn() @@ -115,14 +87,16 @@ class vmmNetwork(vmmLibvirtObject): self._backend = None self._kick_conn() + + ############################### + # XML/config handling parsing # + ############################### + def get_autostart(self): return self._backend.autostart() def set_autostart(self, value): self._backend.setAutostart(value) - def tick(self): - self.force_update_status() - def set_qos(self, **kwargs): xmlobj = self._get_xmlobj_to_define() q = xmlobj.bandwidth @@ -132,11 +106,6 @@ class vmmNetwork(vmmLibvirtObject): self.redefine_cached() return self.is_active() - - ############### - # XML parsing # - ############### - def get_uuid(self): return self.get_xmlobj().uuid def get_bridge_device(self): diff --git a/virtManager/nodedev.py b/virtManager/nodedev.py index c30c3b506..e454b27c9 100644 --- a/virtManager/nodedev.py +++ b/virtManager/nodedev.py @@ -28,12 +28,16 @@ def _parse_convert(conn, parsexml=None): class vmmNodeDevice(vmmLibvirtObject): + _conn_tick_poll_param = "pollnodedev" + def __init__(self, conn, backend, key): vmmLibvirtObject.__init__(self, conn, backend, key, _parse_convert) self._name = key def _XMLDesc(self, flags): return self._backend.XMLDesc(flags) + def _get_backend_status(self): + return self._STATUS_ACTIVE def is_active(self): return True diff --git a/virtManager/serialcon.py b/virtManager/serialcon.py index c982100e4..92c20290d 100644 --- a/virtManager/serialcon.py +++ b/virtManager/serialcon.py @@ -320,7 +320,7 @@ class vmmSerialConsole(vmmGObject): self.error_label = None self.init_ui() - self.vm.connect("status-changed", self.vm_status_changed) + self.vm.connect("state-changed", self.vm_status_changed) def init_terminal(self): self.terminal = Vte.Terminal() diff --git a/virtManager/storagelist.py b/virtManager/storagelist.py index 04e0791ff..12564f672 100644 --- a/virtManager/storagelist.py +++ b/virtManager/storagelist.py @@ -384,7 +384,7 @@ class vmmStorageList(vmmGObjectUI): pool.disconnect_by_func(self._pool_changed) except: pass - pool.connect("status-changed", self._pool_changed) + pool.connect("state-changed", self._pool_changed) pool.connect("refreshed", self._pool_changed) name = pool.get_name() diff --git a/virtManager/storagepool.py b/virtManager/storagepool.py index 1a32a8898..1b14567c1 100644 --- a/virtManager/storagepool.py +++ b/virtManager/storagepool.py @@ -47,6 +47,9 @@ class vmmStorageVolume(vmmLibvirtObject): self._backend.key(), e) raise + def _get_backend_status(self): + return self._STATUS_ACTIVE + ########### # Actions # @@ -100,13 +103,12 @@ class vmmStoragePool(vmmLibvirtObject): "refreshed": (GObject.SignalFlags.RUN_FIRST, None, []) } + _conn_tick_poll_param = "pollpool" + def __init__(self, conn, backend, key): vmmLibvirtObject.__init__(self, conn, backend, key, StoragePool) - self._active = True - self._support_isactive = None self._last_refresh_time = 0 - self._volumes = {} self.tick() @@ -120,47 +122,22 @@ class vmmStoragePool(vmmLibvirtObject): return self._backend.XMLDesc(flags) def _define(self, xml): return self.conn.define_pool(xml) + def _check_supports_isactive(self): + return self.conn.check_support( + self.conn.SUPPORT_POOL_ISACTIVE, self._backend) + def _get_backend_status(self): + return self._backend_get_active() + + def _kick_conn(self): + self.conn.schedule_priority_tick(pollpool=True) + def tick(self): + self.force_update_status() ########### # Actions # ########### - def is_active(self): - return self._active - def _backend_get_active(self): - if self._support_isactive is None: - self._support_isactive = self.conn.check_support( - self.conn.SUPPORT_POOL_ISACTIVE, self._backend) - - if not self._support_isactive: - return True - return bool(self._backend.isActive()) - - def _set_active(self, state): - if state == self._active: - return - - self._active = state - self._invalidate_xml() - self.idle_emit("status-changed") - - def _kick_conn(self): - self.conn.schedule_priority_tick(pollpool=True) - def tick(self): - self._set_active(self._backend_get_active()) - - def set_autostart(self, value): - self._backend.setAutostart(value) - def get_autostart(self): - return self._backend.autostart() - - def can_change_alloc(self): - typ = self.get_type() - return (typ in [StoragePool.TYPE_LOGICAL]) - def supports_volume_creation(self): - return self.get_xmlobj().supports_volume_creation() - def start(self): self._backend.create(0) self._kick_conn() @@ -212,9 +189,20 @@ class vmmStoragePool(vmmLibvirtObject): self._volumes = allvols - ################# - # XML accessors # - ################# + ######################### + # XML/config operations # + ######################### + + def set_autostart(self, value): + self._backend.setAutostart(value) + def get_autostart(self): + return self._backend.autostart() + + def can_change_alloc(self): + typ = self.get_type() + return (typ in [StoragePool.TYPE_LOGICAL]) + def supports_volume_creation(self): + return self.get_xmlobj().supports_volume_creation() def get_type(self): return self.get_xmlobj().type diff --git a/virtManager/systray.py b/virtManager/systray.py index a7fdcdd60..16e8fdee0 100644 --- a/virtManager/systray.py +++ b/virtManager/systray.py @@ -280,7 +280,7 @@ class vmmSystray(vmmGObject): vm = conn.get_vm(connkey) if not vm: return - vm.connect("status-changed", self.vm_state_changed) + vm.connect("state-changed", self.vm_state_changed) vm_mappings = self.conn_vm_menuitems[uri] if connkey in vm_mappings: