mirror of
https://github.com/virt-manager/virt-manager.git
synced 2024-10-27 01:55:20 +03:00
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:
parent
01bf07ba11
commit
a3f8d73a9c
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
@ -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)
|
||||||
|
@ -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())])
|
||||||
|
@ -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"
|
||||||
|
@ -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):
|
||||||
"""
|
"""
|
||||||
|
@ -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:
|
||||||
|
@ -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):
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user