diff --git a/src/virtManager/choosecd.py b/src/virtManager/choosecd.py index a0925215a..60a75f467 100644 --- a/src/virtManager/choosecd.py +++ b/src/virtManager/choosecd.py @@ -131,6 +131,7 @@ class vmmChooseCD(gobject.GObject): try: widget = self.window.get_widget("cd-path") uihelpers.init_optical_combo(widget) + uihelpers.populate_optical_combo(self.conn, widget) self.window.get_widget("physical-media").set_sensitive(True) except Exception, e: logging.error("Unable to create optical-helper widget: '%s'", e) diff --git a/src/virtManager/connection.py b/src/virtManager/connection.py index 5c9c1fc76..e181ca356 100644 --- a/src/virtManager/connection.py +++ b/src/virtManager/connection.py @@ -78,6 +78,11 @@ class vmmConnection(gobject.GObject): "nodedev-removed": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, [str, str]), + "optical-added": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + [object]), + "optical-removed": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + [str]), + "resources-sampled": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, []), "state-changed": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, @@ -118,6 +123,8 @@ class vmmConnection(gobject.GObject): self.nodedevs = {} # Physical network interfaces: name (eth0) -> vmmNetDevice self.netdevs = {} + # Physical media devices: vmmMediaDevice.key -> vmmMediaDevice + self.opticaldevs = {} # Connection Storage pools: name -> vmmInterface self.interfaces = {} # Connection Storage pools: UUID -> vmmStoragePool @@ -133,21 +140,30 @@ class vmmConnection(gobject.GObject): self.hostinfo = None self.hal_helper = hal_helper + self.hal_helper_remove_sig = None self.netdev_initialized = False self.netdev_error = "" self.netdev_use_libvirt = False + self.optical_initialized = False + self.optical_error = "" ################# # Init routines # ################# + def _set_hal_remove_sig(self): + if not self.hal_helper_remove_sig: + sig = self.hal_helper.connect("device-removed", + self._haldev_removed) + self.hal_helper_remove_sig = sig + def _init_netdev(self): """ Determine how we will be polling for net devices (HAL or libvirt) """ - if self.is_nodedev_capable() and self.interface_capable and False: + if self.is_nodedev_capable() and self.interface_capable: try: self._build_libvirt_netdev_list() self.netdev_use_libvirt = True @@ -164,14 +180,14 @@ class vmmConnection(gobject.GObject): if not error: self.hal_helper.connect("netdev-added", self._netdev_added) - self.hal_helper.connect("device-removed", - self._haldev_removed) + self._set_hal_remove_sig() + else: self.netdev_error = _("Could not initialize HAL for " "interface listing: %s") % error else: self.netdev_error = _("Libvirt version does not support " - "physical interface listing") + "physical interface listing.") self.netdev_initialized = True if self.netdev_error: @@ -182,6 +198,31 @@ class vmmConnection(gobject.GObject): else: logging.debug("Using HAL for netdev enumeration") + def _init_optical(self): + if self.hal_helper: + if self.is_remote(): + self.optical_error = _("Libvirt version does not support " + "optical media listing.") + + else: + error = self.hal_helper.get_init_error() + if not error: + self.hal_helper.connect("optical-added", + self._optical_added) + self._set_hal_remove_sig() + + else: + self.optical_error = _("Could not initialize HAL for " + "optical listing: %s") % error + else: + self.optical_error = _("Libvirt version does not support " + "optical media listing.") + + self.optical_initialized = True + if self.optical_error: + logging.debug(self.optical_error) + else: + logging.debug("Using HAL for optical enumeration") ######################## # General data getters # @@ -232,12 +273,15 @@ class vmmConnection(gobject.GObject): return (self.hostinfo[4] * self.hostinfo[5] * self.hostinfo[6] * self.hostinfo[7]) - def connect(self, name, callback): - handle_id = gobject.GObject.connect(self, name, callback) + def connect(self, name, callback, *args): + handle_id = gobject.GObject.connect(self, name, callback, *args) if name == "vm-added": for uuid in self.vms.keys(): self.emit("vm-added", self.uri, uuid) + elif name == "optical-added": + for dev in self.opticaldevs.values(): + self.emit("optical-added", dev) return handle_id @@ -594,6 +638,19 @@ class vmmConnection(gobject.GObject): # Update listeners # #################### + def _haldev_removed(self, ignore, hal_path): + # Physical net device + for name, obj in self.netdevs.items(): + if obj.get_hal_path() == hal_path: + del self.netdevs[name] + 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) + def _netdev_added(self, ignore, netdev): name = netdev.get_name() if self.netdevs.has_key(name): @@ -601,12 +658,13 @@ class vmmConnection(gobject.GObject): self.netdevs[name] = netdev - def _haldev_removed(self, ignore, hal_path): - for name, obj in self.netdevs.items(): - if obj.get_hal_path() == hal_path: - del self.netdevs[name] - return + def _optical_added(self, ignore, dev): + key = dev.get_key() + if self.opticaldevs.has_key(key): + return + self.opticaldevs[key] = dev + self.emit("optical-added", dev) ###################################### # Connection closing/opening methods # @@ -1222,10 +1280,13 @@ class vmmConnection(gobject.GObject): (startVMs, newVMs, oldVMs, self.vms, self.activeUUIDs) = self._update_vms() - # Make sure netdev polling is setup + # Make sure device polling is setup if not self.netdev_initialized: self._init_netdev() + if not self.optical_initialized: + self._init_optical() + def tick_send_signals(): """ Responsible for signaling the UI for any updates. All possible UI diff --git a/src/virtManager/create.py b/src/virtManager/create.py index 94720ec35..a94413337 100644 --- a/src/virtManager/create.py +++ b/src/virtManager/create.py @@ -79,6 +79,7 @@ class vmmCreate(gobject.GObject): self.guest = None self.usepool = False self.storage_browser = None + self.conn_signals = [] self.topwin = self.window.get_widget("vmm-create") self.err = vmmErrorDialog(self.topwin, @@ -157,6 +158,11 @@ class vmmCreate(gobject.GObject): if self.conn == newconn: return + if self.conn: + for signal in self.conn_signals: + self.conn.disconnect(signal) + self.conn_signals = [] + self.conn = newconn if self.conn: self.set_conn_state() @@ -238,16 +244,7 @@ class vmmCreate(gobject.GObject): # Physical CD-ROM model cd_list = self.window.get_widget("install-local-cdrom-combo") - cd_radio = self.window.get_widget("install-local-cdrom") - - # FIXME: We should disable all this if on a remote connection - try: - uihelpers.init_optical_combo(cd_list) - except Exception, e: - logging.exception("Unable to create optical-helper widget: '%s'", e) - cd_radio.set_sensitive(False) - cd_list.set_sensitive(False) - util.tooltip_wrapper(self.window.get_widget("install-local-cdrom-box"), _("Error listing CD-ROM devices.")) + uihelpers.init_optical_combo(cd_list) # Networking # [ interface type, device name, label, sensitive ] @@ -302,7 +299,6 @@ class vmmCreate(gobject.GObject): self.populate_os_type_model() self.window.get_widget("install-os-type").set_active(0) - # Install local/iso self.window.get_widget("install-local-box").child.set_text("") iso_model = self.window.get_widget("install-local-box").get_model() self.populate_media_model(iso_model, self.conn.config_get_iso_paths()) @@ -411,9 +407,20 @@ class vmmCreate(gobject.GObject): iso_option = self.window.get_widget("install-local-iso") cdrom_option = self.window.get_widget("install-local-cdrom") + # Install local/iso + cdrom_list = self.window.get_widget("install-local-cdrom-combo") + try: + sigs = uihelpers.populate_optical_combo(self.conn, cdrom_list) + self.conn_signals.extend(sigs) + except Exception, e: + logging.exception("Unable to populate optical-helper widget: '%s'", e) + cdrom_option.set_sensitive(False) + util.tooltip_wrapper( + self.window.get_widget("install-local-cdrom-box"), + _("Error listing CD-ROM devices.")) self.window.get_widget("install-local-cdrom-box").set_sensitive(is_local) # Don't select physical CDROM if no valid media is present - use_cd = (self.window.get_widget("install-local-cdrom-combo").get_active() >= 0) + use_cd = (cdrom_list.get_active() >= 0) if use_cd: cdrom_option.set_active(True) else: diff --git a/src/virtManager/halhelper.py b/src/virtManager/halhelper.py index a8c1b8f89..0a7e714fe 100644 --- a/src/virtManager/halhelper.py +++ b/src/virtManager/halhelper.py @@ -122,7 +122,6 @@ class vmmHalHelper(gobject.GObject): ############################# def populate_opt_media(self): - optical_info = {} for path in self.hal_iface.FindDeviceByCapability("storage.cdrom"): # Make sure we only populate CDROM devs if not self.is_cdrom(path): diff --git a/src/virtManager/mediadev.py b/src/virtManager/mediadev.py index 2706addb5..d263b8ae6 100644 --- a/src/virtManager/mediadev.py +++ b/src/virtManager/mediadev.py @@ -28,11 +28,6 @@ class vmmMediaDevice(gobject.GObject): gobject.TYPE_NONE, []), } - def __init__(self): - self.__gobject_init__() - - self.bus = None - def __init__(self, path, key, media_label, media_key): self.__gobject_init__() diff --git a/src/virtManager/uihelpers.py b/src/virtManager/uihelpers.py index 294a874c1..1835b0b47 100644 --- a/src/virtManager/uihelpers.py +++ b/src/virtManager/uihelpers.py @@ -25,7 +25,6 @@ import gtk from virtinst import VirtualNetworkInterface -from virtManager.halhelper import vmmHalHelper from virtManager.error import vmmErrorDialog OPTICAL_DEV_PATH = 0 @@ -264,13 +263,19 @@ def init_optical_combo(widget, empty_sensitive=False): if not empty_sensitive: widget.add_attribute(text, 'sensitive', 2) - helper = vmmHalHelper() - helper.connect("optical-added", optical_added, widget) - helper.connect("device-removed", optical_removed, widget) +def populate_optical_combo(conn, widget): + sigs = [] + + widget.get_model().clear() + + sigs.append(conn.connect("optical-added", optical_added, widget)) + sigs.append(conn.connect("optical-removed", optical_removed, widget)) widget.set_active(-1) optical_set_default_selection(widget) + return sigs + def set_row_from_object(row): obj = row[OPTICAL_MEDIADEV] row[OPTICAL_DEV_PATH] = obj.get_path() @@ -288,7 +293,11 @@ def optical_removed(ignore_helper, key, widget): if row[OPTICAL_DEV_KEY] == key: # Whole device removed del(model[idx]) - widget.set_active(-1) + + if idx > active and active != -1: + widget.set_active(active-1) + elif idx == active: + widget.set_active(-1) idx += 1