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.
This commit is contained in:
Cole Robinson 2015-04-09 18:02:42 -04:00
parent 01bf07ba11
commit a3f8d73a9c
15 changed files with 181 additions and 216 deletions

View File

@ -678,6 +678,8 @@ class vmmConnection(vmmGObject):
obj = self._vms.get(domain.name(), None) obj = self._vms.get(domain.name(), None)
if not obj: if not obj:
return return
# Uses forcesignal=True
self.idle_add(obj.refresh_xml, True) self.idle_add(obj.refresh_xml, True)
def _domain_lifecycle_event(self, conn, domain, event, reason, userdata): 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) self.idle_add(obj.force_update_status, True)
if event == libvirt.VIR_DOMAIN_EVENT_DEFINED: if event == libvirt.VIR_DOMAIN_EVENT_DEFINED:
# Uses forcesignal=True
self.idle_add(obj.refresh_xml, True) self.idle_add(obj.refresh_xml, True)
else: else:
self.schedule_priority_tick(pollvm=True, force=True) self.schedule_priority_tick(pollvm=True, force=True)
@ -706,6 +709,7 @@ class vmmConnection(vmmGObject):
self.idle_add(obj.force_update_status, True) self.idle_add(obj.force_update_status, True)
if event == getattr(libvirt, "VIR_NETWORK_EVENT_DEFINED", 0): if event == getattr(libvirt, "VIR_NETWORK_EVENT_DEFINED", 0):
# Uses forcesignal=True
self.idle_add(obj.refresh_xml, True) self.idle_add(obj.refresh_xml, True)
else: else:
self.schedule_priority_tick(pollnet=True, force=True) self.schedule_priority_tick(pollnet=True, force=True)

View File

@ -51,7 +51,7 @@ class vmmConsolePages(vmmGObjectUI):
self.vm = vm self.vm = vm
self._pointer_is_grabbed = False self._pointer_is_grabbed = False
self._change_title() self._change_title()
self.vm.connect("config-changed", self._change_title) self.vm.connect("state-changed", self._change_title)
self._force_resize = False self._force_resize = False
# State for disabling modifiers when keyboard is grabbed # State for disabling modifiers when keyboard is grabbed

View File

@ -1891,7 +1891,7 @@ class vmmCreate(vmmGObjectUI):
# Register a status listener, which will restart the # Register a status listener, which will restart the
# guest after the install has finished # guest after the install has finished
def cb(): def cb():
vm.connect_opt_out("status-changed", vm.connect_opt_out("state-changed",
self.check_install_status, guest) self.check_install_status, guest)
return False return False
self.idle_add(cb) self.idle_add(cb)
@ -1925,7 +1925,7 @@ class vmmCreate(vmmGObjectUI):
# will force one final restart. # will force one final restart.
virtinst_guest.continue_install() virtinst_guest.continue_install()
vm.connect_opt_out("status-changed", vm.connect_opt_out("state-changed",
self.check_install_status, None) self.check_install_status, None)
return True return True

View File

@ -574,8 +574,7 @@ class vmmDetails(vmmGObjectUI):
}) })
# Deliberately keep all this after signal connection # Deliberately keep all this after signal connection
self.vm.connect("status-changed", self.refresh_vm_state) self.vm.connect("state-changed", self.refresh_vm_state)
self.vm.connect("config-changed", self.refresh_vm_state)
self.vm.connect("resources-sampled", self.refresh_resources) self.vm.connect("resources-sampled", self.refresh_resources)
self.populate_hw_list() self.populate_hw_list()

View File

@ -177,6 +177,8 @@ class vmmDomainSnapshot(vmmLibvirtObject):
def _XMLDesc(self, flags): def _XMLDesc(self, flags):
return self._backend.getXMLDesc(flags=flags) return self._backend.getXMLDesc(flags=flags)
def _get_backend_status(self):
return self._STATUS_ACTIVE
def delete(self, force=True): def delete(self, force=True):
ignore = force ignore = force
@ -214,6 +216,8 @@ class vmmDomain(vmmLibvirtObject):
"pre-startup": (GObject.SignalFlags.RUN_FIRST, None, [object]), "pre-startup": (GObject.SignalFlags.RUN_FIRST, None, [object]),
} }
_conn_tick_poll_param = "pollvm"
@staticmethod @staticmethod
def pretty_run_status(status, has_saved=False): def pretty_run_status(status, has_saved=False):
if status == libvirt.VIR_DOMAIN_RUNNING: if status == libvirt.VIR_DOMAIN_RUNNING:
@ -302,10 +306,7 @@ class vmmDomain(vmmLibvirtObject):
self._snapshot_list = None self._snapshot_list = None
self._autostart = None self._autostart = None
self._domain_caps = None self._domain_caps = None
self._status_reason = None
self.lastStatus = libvirt.VIR_DOMAIN_SHUTOFF
self._lastStatusReason = getattr(libvirt, "VIR_DOMAIN_SHUTOFF_SHUTDOWN",
1)
self.managedsave_supported = False self.managedsave_supported = False
self.remote_console_supported = False self.remote_console_supported = False
@ -362,7 +363,7 @@ class vmmDomain(vmmLibvirtObject):
self.toggle_sample_mem_stats() self.toggle_sample_mem_stats()
self.toggle_sample_cpu_stats() self.toggle_sample_cpu_stats()
self.force_update_status(from_event=True, log=False) self.force_update_status(from_event=True)
# Prime caches # Prime caches
self.refresh_xml() self.refresh_xml()
@ -426,10 +427,14 @@ class vmmDomain(vmmLibvirtObject):
return self._id return self._id
def status(self): def status(self):
return self.lastStatus return self._normalize_status(self._get_status())
def status_reason(self): 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): def get_cloning(self):
return self.cloning return self.cloning
@ -520,6 +525,9 @@ class vmmDomain(vmmLibvirtObject):
def _invalidate_xml(self): def _invalidate_xml(self):
vmmLibvirtObject._invalidate_xml(self) vmmLibvirtObject._invalidate_xml(self)
self._id = None 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): def _lookup_device_to_define(self, origdev, guest=None):
if guest is None: if guest is None:
@ -1034,6 +1042,8 @@ class vmmDomain(vmmLibvirtObject):
self.conn.define_domain(newxml) self.conn.define_domain(newxml)
def _XMLDesc(self, flags): def _XMLDesc(self, flags):
return self._backend.XMLDesc(flags) return self._backend.XMLDesc(flags)
def _get_backend_status(self):
return self._backend.info()[0]
def get_autostart(self): def get_autostart(self):
if self._autostart is None: if self._autostart is None:
@ -1345,7 +1355,7 @@ class vmmDomain(vmmLibvirtObject):
self.shutdown() self.shutdown()
def add_reboot(): def add_reboot():
self.reboot_listener = self.connect_opt_out("status-changed", self.reboot_listener = self.connect_opt_out("state-changed",
reboot_listener, self) reboot_listener, self)
self.idle_add(add_reboot) self.idle_add(add_reboot)
@ -1716,48 +1726,6 @@ class vmmDomain(vmmLibvirtObject):
status = libvirt.VIR_DOMAIN_NOSTATE status = libvirt.VIR_DOMAIN_NOSTATE
return vm_status_icons[status] 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): def inspection_data_updated(self):
self.idle_emit("inspection-changed") self.idle_emit("inspection-changed")
@ -1934,8 +1902,8 @@ class vmmDomain(vmmLibvirtObject):
if stats_update: if stats_update:
self._tick_stats(info) self._tick_stats(info)
if not self._using_events(): # This is a no-op if using events
self._update_status(info[0]) self.force_update_status(newstatus=info[0])
if stats_update: if stats_update:
self.idle_emit("resources-sampled") self.idle_emit("resources-sampled")
@ -2015,7 +1983,7 @@ class vmmDomainVirtinst(vmmDomain):
return self._backend.autostart return self._backend.autostart
def set_autostart(self, val): def set_autostart(self, val):
self._backend.autostart = bool(val) self._backend.autostart = bool(val)
self.emit("config-changed") self.emit("state-changed")
def _using_events(self): def _using_events(self):
return False return False
@ -2038,7 +2006,7 @@ class vmmDomainVirtinst(vmmDomain):
def _define(self, newxml): def _define(self, newxml):
ignore = newxml ignore = newxml
self.emit("config-changed") self.emit("state-changed")
def _invalidate_xml(self): def _invalidate_xml(self):
vmmDomain._invalidate_xml(self) vmmDomain._invalidate_xml(self)

View File

@ -703,7 +703,7 @@ class vmmHost(vmmGObjectUI):
net.disconnect_by_func(self.refresh_network) net.disconnect_by_func(self.refresh_network)
except: except:
pass 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", model.append([net.get_connkey(), net.get_name(), "network-idle",
Gtk.IconSize.LARGE_TOOLBAR, Gtk.IconSize.LARGE_TOOLBAR,
bool(net.is_active())]) bool(net.is_active())])
@ -955,7 +955,7 @@ class vmmHost(vmmGObjectUI):
iface.disconnect_by_func(self.refresh_interface) iface.disconnect_by_func(self.refresh_interface)
except: except:
pass pass
iface.connect("status-changed", self.refresh_interface) iface.connect("state-changed", self.refresh_interface)
model.append([iface.get_connkey(), iface.get_name(), model.append([iface.get_connkey(), iface.get_name(),
"network-idle", Gtk.IconSize.LARGE_TOOLBAR, "network-idle", Gtk.IconSize.LARGE_TOOLBAR,
bool(iface.is_active())]) bool(iface.is_active())])

View File

@ -24,16 +24,14 @@ from .libvirtobject import vmmLibvirtObject
class vmmInterface(vmmLibvirtObject): class vmmInterface(vmmLibvirtObject):
_conn_tick_poll_param = "polliface"
def __init__(self, conn, backend, key): def __init__(self, conn, backend, key):
vmmLibvirtObject.__init__(self, conn, backend, key, Interface) vmmLibvirtObject.__init__(self, conn, backend, key, Interface)
self._active = True
(self._inactive_xml_flags, (self._inactive_xml_flags,
self._active_xml_flags) = self.conn.get_interface_flags(self._backend) self._active_xml_flags) = self.conn.get_interface_flags(self._backend)
self._support_isactive = None
self.tick() self.tick()
# Routines from vmmLibvirtObject # Routines from vmmLibvirtObject
@ -41,36 +39,21 @@ class vmmInterface(vmmLibvirtObject):
return self._backend.XMLDesc(flags) return self._backend.XMLDesc(flags)
def _define(self, xml): def _define(self, xml):
return self.conn.define_interface(xml) return self.conn.define_interface(xml)
def _check_supports_isactive(self):
def _set_active(self, state): return self.conn.check_support(
if state == self._active: self.conn.SUPPORT_INTERFACE_ISACTIVE, self._backend)
return def _get_backend_status(self):
return self._backend_get_active()
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 _kick_conn(self): def _kick_conn(self):
self.conn.schedule_priority_tick(polliface=True) self.conn.schedule_priority_tick(polliface=True)
def tick(self):
self.force_update_status()
#####################
# Object operations #
#####################
def start(self): def start(self):
self._backend.create(0) self._backend.create(0)
@ -87,6 +70,14 @@ class vmmInterface(vmmLibvirtObject):
self._backend.undefine() self._backend.undefine()
self._kick_conn() self._kick_conn()
################
# XML routines #
################
def get_mac(self):
return self.get_xmlobj().macaddr
def is_bridge(self): def is_bridge(self):
typ = self.get_type() typ = self.get_type()
return typ == "bridge" return typ == "bridge"

View File

@ -27,12 +27,18 @@ from .baseclass import vmmGObject
class vmmLibvirtObject(vmmGObject): class vmmLibvirtObject(vmmGObject):
__gsignals__ = { __gsignals__ = {
"status-changed": (GObject.SignalFlags.RUN_FIRST, None, []), "state-changed": (GObject.SignalFlags.RUN_FIRST, None, []),
"config-changed": (GObject.SignalFlags.RUN_FIRST, None, []),
"started": (GObject.SignalFlags.RUN_FIRST, None, []), "started": (GObject.SignalFlags.RUN_FIRST, None, []),
"stopped": (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): def __init__(self, conn, backend, key, parseclass):
vmmGObject.__init__(self) vmmGObject.__init__(self)
self._conn = conn self._conn = conn
@ -40,6 +46,9 @@ class vmmLibvirtObject(vmmGObject):
self._key = key self._key = key
self._parseclass = parseclass self._parseclass = parseclass
self.__status = self._STATUS_ACTIVE
self._support_isactive = None
self._xmlobj = None self._xmlobj = None
self._xmlobj_to_define = None self._xmlobj_to_define = None
self._is_xml_valid = False self._is_xml_valid = False
@ -52,6 +61,7 @@ class vmmLibvirtObject(vmmGObject):
self._name = None self._name = None
self.get_name() self.get_name()
@staticmethod @staticmethod
def log_redefine_xml_diff(obj, origxml, newxml): def log_redefine_xml_diff(obj, origxml, newxml):
objname = "<%s name=%s>" % (obj.__class__.__name__, obj.get_name()) objname = "<%s name=%s>" % (obj.__class__.__name__, obj.get_name())
@ -105,7 +115,7 @@ class vmmLibvirtObject(vmmGObject):
finally: finally:
self._invalidate_xml() self._invalidate_xml()
self.emit("config-changed") self.emit("state-changed")
############################################################# #############################################################
@ -116,6 +126,10 @@ class vmmLibvirtObject(vmmGObject):
raise NotImplementedError() raise NotImplementedError()
def _using_events(self): def _using_events(self):
return False return False
def _check_supports_isactive(self):
return False
def _get_backend_status(self):
raise NotImplementedError()
def _define(self, xml): def _define(self, xml):
ignore = xml ignore = xml
@ -124,10 +138,6 @@ class vmmLibvirtObject(vmmGObject):
def delete(self, force=True): def delete(self, force=True):
ignore = force ignore = force
def force_update_status(self, from_event=False, log=True):
ignore = from_event
ignore = log
def get_name(self): def get_name(self):
if self._name is None: if self._name is None:
self._name = self._backend_get_name() self._name = self._backend_get_name()
@ -137,16 +147,65 @@ class vmmLibvirtObject(vmmGObject):
return self._backend.name() 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 # # Public XML API #
################## ##################
def refresh_xml(self, forcesignal=False): 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 changed since last refresh
:param forcesignal: Send config-changed unconditionally :param forcesignal: Send state-changed unconditionally
""" """
origxml = None origxml = None
if self._xmlobj: if self._xmlobj:
@ -159,7 +218,7 @@ class vmmLibvirtObject(vmmGObject):
self._is_xml_valid = True self._is_xml_valid = True
if forcesignal or origxml != active_xml: 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): def get_xmlobj(self, inactive=False, refresh_if_nec=True):
""" """

View File

@ -588,8 +588,7 @@ class vmmManager(vmmGObjectUI):
if self.vm_row_key(vm) in self.rows: if self.vm_row_key(vm) in self.rows:
return return
vm.connect("config-changed", self.vm_config_changed) vm.connect("state-changed", self.vm_changed)
vm.connect("status-changed", self.vm_status_changed)
vm.connect("resources-sampled", self.vm_row_updated) vm.connect("resources-sampled", self.vm_row_updated)
vm.connect("inspection-changed", self.vm_inspection_changed) vm.connect("inspection-changed", self.vm_inspection_changed)
@ -778,12 +777,15 @@ class vmmManager(vmmGObjectUI):
return return
self.widget("vm-list").get_model().row_changed(row.path, row.iter) 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) row = self.rows.get(self.vm_row_key(vm), None)
if row is None: if row is None:
return return
try: try:
if vm == self.current_vm():
self.update_current_selection()
name = vm.get_name_or_title() name = vm.get_name_or_title()
status = vm.run_status() status = vm.run_status()
@ -803,25 +805,6 @@ class vmmManager(vmmGObjectUI):
self.vm_row_updated(vm) 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): def vm_inspection_changed(self, vm):
row = self.rows.get(self.vm_row_key(vm), None) row = self.rows.get(self.vm_row_key(vm), None)
if row is None: if row is None:

View File

@ -18,8 +18,6 @@
# MA 02110-1301 USA. # MA 02110-1301 USA.
# #
import logging
import ipaddr import ipaddr
from virtinst import Network from virtinst import Network
@ -41,11 +39,10 @@ def _make_addr_str(addrStr, prefix, netmaskStr):
class vmmNetwork(vmmLibvirtObject): class vmmNetwork(vmmLibvirtObject):
_conn_tick_poll_param = "pollnet"
def __init__(self, conn, backend, key): def __init__(self, conn, backend, key):
vmmLibvirtObject.__init__(self, conn, backend, key, Network) vmmLibvirtObject.__init__(self, conn, backend, key, Network)
self._active = True
self._support_isactive = None
self.force_update_status(from_event=True) self.force_update_status(from_event=True)
@ -60,47 +57,22 @@ class vmmNetwork(vmmLibvirtObject):
return self.conn.define_network(xml) return self.conn.define_network(xml)
def _using_events(self): def _using_events(self):
return self.conn.using_network_events 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 # # 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): def start(self):
self._backend.create() self._backend.create()
self._kick_conn() self._kick_conn()
@ -115,14 +87,16 @@ class vmmNetwork(vmmLibvirtObject):
self._backend = None self._backend = None
self._kick_conn() self._kick_conn()
###############################
# XML/config handling parsing #
###############################
def get_autostart(self): def get_autostart(self):
return self._backend.autostart() return self._backend.autostart()
def set_autostart(self, value): def set_autostart(self, value):
self._backend.setAutostart(value) self._backend.setAutostart(value)
def tick(self):
self.force_update_status()
def set_qos(self, **kwargs): def set_qos(self, **kwargs):
xmlobj = self._get_xmlobj_to_define() xmlobj = self._get_xmlobj_to_define()
q = xmlobj.bandwidth q = xmlobj.bandwidth
@ -132,11 +106,6 @@ class vmmNetwork(vmmLibvirtObject):
self.redefine_cached() self.redefine_cached()
return self.is_active() return self.is_active()
###############
# XML parsing #
###############
def get_uuid(self): def get_uuid(self):
return self.get_xmlobj().uuid return self.get_xmlobj().uuid
def get_bridge_device(self): def get_bridge_device(self):

View File

@ -28,12 +28,16 @@ def _parse_convert(conn, parsexml=None):
class vmmNodeDevice(vmmLibvirtObject): class vmmNodeDevice(vmmLibvirtObject):
_conn_tick_poll_param = "pollnodedev"
def __init__(self, conn, backend, key): def __init__(self, conn, backend, key):
vmmLibvirtObject.__init__(self, conn, backend, key, _parse_convert) vmmLibvirtObject.__init__(self, conn, backend, key, _parse_convert)
self._name = key self._name = key
def _XMLDesc(self, flags): def _XMLDesc(self, flags):
return self._backend.XMLDesc(flags) return self._backend.XMLDesc(flags)
def _get_backend_status(self):
return self._STATUS_ACTIVE
def is_active(self): def is_active(self):
return True return True

View File

@ -320,7 +320,7 @@ class vmmSerialConsole(vmmGObject):
self.error_label = None self.error_label = None
self.init_ui() 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): def init_terminal(self):
self.terminal = Vte.Terminal() self.terminal = Vte.Terminal()

View File

@ -384,7 +384,7 @@ class vmmStorageList(vmmGObjectUI):
pool.disconnect_by_func(self._pool_changed) pool.disconnect_by_func(self._pool_changed)
except: except:
pass pass
pool.connect("status-changed", self._pool_changed) pool.connect("state-changed", self._pool_changed)
pool.connect("refreshed", self._pool_changed) pool.connect("refreshed", self._pool_changed)
name = pool.get_name() name = pool.get_name()

View File

@ -47,6 +47,9 @@ class vmmStorageVolume(vmmLibvirtObject):
self._backend.key(), e) self._backend.key(), e)
raise raise
def _get_backend_status(self):
return self._STATUS_ACTIVE
########### ###########
# Actions # # Actions #
@ -100,13 +103,12 @@ class vmmStoragePool(vmmLibvirtObject):
"refreshed": (GObject.SignalFlags.RUN_FIRST, None, []) "refreshed": (GObject.SignalFlags.RUN_FIRST, None, [])
} }
_conn_tick_poll_param = "pollpool"
def __init__(self, conn, backend, key): def __init__(self, conn, backend, key):
vmmLibvirtObject.__init__(self, conn, backend, key, StoragePool) vmmLibvirtObject.__init__(self, conn, backend, key, StoragePool)
self._active = True
self._support_isactive = None
self._last_refresh_time = 0 self._last_refresh_time = 0
self._volumes = {} self._volumes = {}
self.tick() self.tick()
@ -120,47 +122,22 @@ class vmmStoragePool(vmmLibvirtObject):
return self._backend.XMLDesc(flags) return self._backend.XMLDesc(flags)
def _define(self, xml): def _define(self, xml):
return self.conn.define_pool(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 # # 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): def start(self):
self._backend.create(0) self._backend.create(0)
self._kick_conn() self._kick_conn()
@ -212,9 +189,20 @@ class vmmStoragePool(vmmLibvirtObject):
self._volumes = allvols 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): def get_type(self):
return self.get_xmlobj().type return self.get_xmlobj().type

View File

@ -280,7 +280,7 @@ class vmmSystray(vmmGObject):
vm = conn.get_vm(connkey) vm = conn.get_vm(connkey)
if not vm: if not vm:
return return
vm.connect("status-changed", self.vm_state_changed) vm.connect("state-changed", self.vm_state_changed)
vm_mappings = self.conn_vm_menuitems[uri] vm_mappings = self.conn_vm_menuitems[uri]
if connkey in vm_mappings: if connkey in vm_mappings: