Allow using node device APIs for CDROM enumeration.
One piece of info libvirt doesn't provide for us in the media label name, other than that we have feature parity.
This commit is contained in:
parent
5d9d6a6fc4
commit
51c9dce24b
|
@ -36,6 +36,7 @@ from virtManager.network import vmmNetwork
|
|||
from virtManager.storagepool import vmmStoragePool
|
||||
from virtManager.interface import vmmInterface
|
||||
from virtManager.netdev import vmmNetDevice
|
||||
from virtManager.mediadev import vmmMediaDevice
|
||||
|
||||
class vmmConnection(gobject.GObject):
|
||||
__gsignals__ = {
|
||||
|
@ -148,6 +149,7 @@ class vmmConnection(gobject.GObject):
|
|||
|
||||
self.optical_initialized = False
|
||||
self.optical_error = ""
|
||||
self.optical_use_libvirt = False
|
||||
|
||||
#################
|
||||
# Init routines #
|
||||
|
@ -205,7 +207,16 @@ class vmmConnection(gobject.GObject):
|
|||
logging.debug("Using HAL for netdev enumeration")
|
||||
|
||||
def _init_optical(self):
|
||||
if self.get_hal_helper():
|
||||
if self.is_nodedev_capable():
|
||||
try:
|
||||
self.connect("nodedev-added", self._nodedev_optical_added)
|
||||
self.connect("nodedev-removed", self._nodedev_optical_removed)
|
||||
self.optical_use_libvirt = True
|
||||
except Exception, e:
|
||||
self.optical_error = _("Could build optical interface "
|
||||
"list via libvirt: %s") % str(e)
|
||||
|
||||
elif self.get_hal_helper():
|
||||
hal_helper = self.get_hal_helper()
|
||||
|
||||
if self.is_remote():
|
||||
|
@ -229,7 +240,10 @@ class vmmConnection(gobject.GObject):
|
|||
if self.optical_error:
|
||||
logging.debug(self.optical_error)
|
||||
else:
|
||||
logging.debug("Using HAL for optical enumeration")
|
||||
if self.optical_use_libvirt:
|
||||
logging.debug("Using libvirt API for optical enumeration")
|
||||
else:
|
||||
logging.debug("Using HAL for optical enumeration")
|
||||
|
||||
########################
|
||||
# General data getters #
|
||||
|
@ -289,6 +303,9 @@ class vmmConnection(gobject.GObject):
|
|||
elif name == "optical-added":
|
||||
for dev in self.opticaldevs.values():
|
||||
self.emit("optical-added", dev)
|
||||
elif name == "nodedev-added":
|
||||
for key in self.nodedevs.keys():
|
||||
self.emit("nodedev-added", self.get_uri(), key)
|
||||
|
||||
return handle_id
|
||||
|
||||
|
@ -558,6 +575,8 @@ class vmmConnection(gobject.GObject):
|
|||
return self.pools[uuid]
|
||||
def get_interface(self, name):
|
||||
return self.interfaces[name]
|
||||
def get_nodedev(self, name):
|
||||
return self.nodedevs[name]
|
||||
def get_devices(self, devtype=None, devcap=None):
|
||||
retdevs = []
|
||||
for vdev in self.nodedevs.values():
|
||||
|
@ -645,6 +664,13 @@ class vmmConnection(gobject.GObject):
|
|||
# Update listeners #
|
||||
####################
|
||||
|
||||
def _remove_optical(self, key):
|
||||
del(self.opticaldevs[key])
|
||||
self.emit("optical-removed", key)
|
||||
def _add_optical(self, key, dev):
|
||||
self.opticaldevs[key] = dev
|
||||
self.emit("optical-added", dev)
|
||||
|
||||
def _haldev_removed(self, ignore, hal_path):
|
||||
# Physical net device
|
||||
for name, obj in self.netdevs.items():
|
||||
|
@ -653,10 +679,8 @@ class vmmConnection(gobject.GObject):
|
|||
return
|
||||
|
||||
for key, obj in self.opticaldevs.items():
|
||||
if obj.get_key() == hal_path:
|
||||
del(self.opticaldevs[key])
|
||||
print "optical-removed %s" % hal_path
|
||||
self.emit("optical-removed", hal_path)
|
||||
if key == hal_path:
|
||||
self._remove_optical(key)
|
||||
|
||||
def _netdev_added(self, ignore, netdev):
|
||||
name = netdev.get_name()
|
||||
|
@ -670,8 +694,24 @@ class vmmConnection(gobject.GObject):
|
|||
if self.opticaldevs.has_key(key):
|
||||
return
|
||||
|
||||
self.opticaldevs[key] = dev
|
||||
self.emit("optical-added", dev)
|
||||
self._add_optical(key, dev)
|
||||
|
||||
def _nodedev_optical_added(self, ignore1, ignore2, name):
|
||||
if self.opticaldevs.has_key(name):
|
||||
return
|
||||
|
||||
vobj = self.get_nodedev(name)
|
||||
mediadev = vmmMediaDevice.mediadev_from_nodedev(self, vobj)
|
||||
if not mediadev:
|
||||
return
|
||||
|
||||
self._add_optical(name, mediadev)
|
||||
|
||||
def _nodedev_optical_removed(self, ignore1, ignore2, name):
|
||||
if not self.opticaldevs.has_key(name):
|
||||
return
|
||||
|
||||
self._remove_optical(name)
|
||||
|
||||
######################################
|
||||
# Connection closing/opening methods #
|
||||
|
|
|
@ -164,7 +164,8 @@ class vmmHalHelper(gobject.GObject):
|
|||
self.emit("device-removed", str(path))
|
||||
|
||||
def add_optical_dev(self, devpath, halpath, media_label, media_hal_path):
|
||||
obj = vmmMediaDevice(devpath, halpath, media_label, media_hal_path)
|
||||
obj = vmmMediaDevice(devpath, halpath, bool(media_label),
|
||||
media_label, media_hal_path)
|
||||
obj.set_hal_media_signals(self)
|
||||
self.emit("optical-added", obj)
|
||||
|
||||
|
|
|
@ -19,6 +19,11 @@
|
|||
#
|
||||
|
||||
import gobject
|
||||
import logging
|
||||
|
||||
import virtinst
|
||||
|
||||
MEDIA_TIMEOUT = 3
|
||||
|
||||
class vmmMediaDevice(gobject.GObject):
|
||||
__gsignals__ = {
|
||||
|
@ -28,14 +33,40 @@ class vmmMediaDevice(gobject.GObject):
|
|||
gobject.TYPE_NONE, []),
|
||||
}
|
||||
|
||||
def __init__(self, path, key, media_label, media_key):
|
||||
@staticmethod
|
||||
def mediadev_from_nodedev(conn, nodedev):
|
||||
if nodedev.device_type != "storage":
|
||||
return None
|
||||
|
||||
if nodedev.drive_type != "cdrom":
|
||||
return None
|
||||
|
||||
path = nodedev.block
|
||||
key = nodedev.name
|
||||
has_media = nodedev.media_available
|
||||
media_label = None
|
||||
media_key = None
|
||||
|
||||
nodedev_obj = conn.vmm.nodeDeviceLookupByName(key)
|
||||
obj = vmmMediaDevice(path, key, has_media, media_label, media_key,
|
||||
nodedev_obj)
|
||||
obj.enable_poll_for_media()
|
||||
|
||||
return obj
|
||||
|
||||
def __init__(self, path, key, has_media, media_label, media_key,
|
||||
nodedev_obj = None):
|
||||
self.__gobject_init__()
|
||||
|
||||
self.path = path
|
||||
self.key = key
|
||||
self._has_media = has_media
|
||||
self.media_label = media_label
|
||||
self.media_key = media_key
|
||||
|
||||
self.nodedev_obj = nodedev_obj
|
||||
self.poll_signal = None
|
||||
|
||||
def get_path(self):
|
||||
return self.path
|
||||
|
||||
|
@ -43,23 +74,27 @@ class vmmMediaDevice(gobject.GObject):
|
|||
return self.key
|
||||
|
||||
def has_media(self):
|
||||
return self.has_media
|
||||
|
||||
return self._has_media
|
||||
def get_media_label(self):
|
||||
return self.media_label
|
||||
def get_media_key(self):
|
||||
return self.media_key
|
||||
|
||||
def set_media(self, media_label, media_key):
|
||||
def set_media(self, has_media, media_label, media_key):
|
||||
self._has_media = has_media
|
||||
self.media_label = media_label
|
||||
self.media_key = media_key
|
||||
def clear_media(self):
|
||||
self.set_media(None, None)
|
||||
self.set_media(None, None, None)
|
||||
|
||||
def pretty_label(self):
|
||||
media_label = self.get_media_label()
|
||||
if not media_label:
|
||||
has_media = self.has_media()
|
||||
if not has_media:
|
||||
media_label = _("No media present")
|
||||
else:
|
||||
media_label = _("Media Unknown")
|
||||
|
||||
return "%s (%s)" % (media_label, self.get_path())
|
||||
|
||||
|
||||
|
@ -75,7 +110,7 @@ class vmmMediaDevice(gobject.GObject):
|
|||
if devpath != self.get_path():
|
||||
return
|
||||
|
||||
self.set_media(media_label, media_key)
|
||||
self.set_media(True, media_label, media_key)
|
||||
self.emit("media-added")
|
||||
|
||||
def hal_media_removed(self, ignore, media_hal_path):
|
||||
|
@ -86,4 +121,46 @@ class vmmMediaDevice(gobject.GObject):
|
|||
self.emit("media-removed")
|
||||
|
||||
|
||||
#########################################
|
||||
# Nodedev API polling for media updates #
|
||||
#########################################
|
||||
def enable_poll_for_media(self):
|
||||
if self.poll_signal:
|
||||
return
|
||||
|
||||
self.poll_signal = gobject.timeout_add(MEDIA_TIMEOUT * 1000,
|
||||
self._poll_for_media)
|
||||
|
||||
def disable_poll_for_media(self):
|
||||
self.poll_signal = None
|
||||
|
||||
def _poll_for_media(self):
|
||||
if not self.poll_signal:
|
||||
return False
|
||||
|
||||
if not self.nodedev_obj:
|
||||
return False
|
||||
|
||||
try:
|
||||
xml = self.nodedev_obj.XMLDesc(0)
|
||||
except:
|
||||
# Assume the device was removed
|
||||
return False
|
||||
|
||||
try:
|
||||
vobj = virtinst.NodeDeviceParser.parse(xml)
|
||||
has_media = vobj.media_available
|
||||
except:
|
||||
logging.exception("Node device CDROM polling failed")
|
||||
return False
|
||||
|
||||
if has_media != self.has_media():
|
||||
self.set_media(has_media, None, None)
|
||||
if has_media:
|
||||
self.emit("media-added")
|
||||
else:
|
||||
self.emit("media-removed")
|
||||
|
||||
return True
|
||||
|
||||
gobject.type_register(vmmMediaDevice)
|
||||
|
|
|
@ -32,7 +32,6 @@ OPTICAL_LABEL = 1
|
|||
OPTICAL_IS_MEDIA_PRESENT = 2
|
||||
OPTICAL_DEV_KEY = 3
|
||||
OPTICAL_MEDIA_KEY = 4
|
||||
OPTICAL_MEDIADEV = 5
|
||||
|
||||
##############################################################
|
||||
# Initialize an error object to use for validation functions #
|
||||
|
@ -253,7 +252,7 @@ def generate_macaddr(conn):
|
|||
def init_optical_combo(widget, empty_sensitive=False):
|
||||
# [Device path, pretty label, has_media?, device key, media key,
|
||||
# vmmMediaDevice]
|
||||
model = gtk.ListStore(str, str, bool, str, str, object)
|
||||
model = gtk.ListStore(str, str, bool, str, str)
|
||||
widget.set_model(model)
|
||||
model.clear()
|
||||
|
||||
|
@ -276,11 +275,10 @@ def populate_optical_combo(conn, widget):
|
|||
|
||||
return sigs
|
||||
|
||||
def set_row_from_object(row):
|
||||
obj = row[OPTICAL_MEDIADEV]
|
||||
def set_row_from_object(row, obj):
|
||||
row[OPTICAL_DEV_PATH] = obj.get_path()
|
||||
row[OPTICAL_LABEL] = obj.pretty_label()
|
||||
row[OPTICAL_IS_MEDIA_PRESENT] = bool(obj.get_media_label())
|
||||
row[OPTICAL_IS_MEDIA_PRESENT] = obj.has_media()
|
||||
row[OPTICAL_DEV_KEY] = obj.get_key()
|
||||
row[OPTICAL_MEDIA_KEY] = obj.get_media_key()
|
||||
|
||||
|
@ -310,10 +308,12 @@ def optical_added(ignore_helper, newobj, widget):
|
|||
newobj.connect("media-removed", optical_media_changed, widget)
|
||||
|
||||
# Brand new device
|
||||
row = [None, None, None, None, None, newobj]
|
||||
set_row_from_object(row)
|
||||
row = [None, None, None, None, None]
|
||||
set_row_from_object(row, newobj)
|
||||
model.append(row)
|
||||
|
||||
optical_set_default_selection(widget)
|
||||
|
||||
def optical_media_changed(newobj, widget):
|
||||
model = widget.get_model()
|
||||
active = widget.get_active()
|
||||
|
@ -324,7 +324,7 @@ def optical_media_changed(newobj, widget):
|
|||
# selection, select the new media.
|
||||
for row in model:
|
||||
if row[OPTICAL_DEV_PATH] == newobj.get_path():
|
||||
set_row_from_object(row)
|
||||
set_row_from_object(row, newobj)
|
||||
has_media = row[OPTICAL_IS_MEDIA_PRESENT]
|
||||
|
||||
if has_media and active == -1:
|
||||
|
@ -334,6 +334,8 @@ def optical_media_changed(newobj, widget):
|
|||
|
||||
idx = idx + 1
|
||||
|
||||
optical_set_default_selection(widget)
|
||||
|
||||
def optical_set_default_selection(widget):
|
||||
# Set the first active cdrom device as selected, otherwise none
|
||||
model = widget.get_model()
|
||||
|
|
Loading…
Reference in New Issue