diff --git a/src/virt-manager.py.in b/src/virt-manager.py.in index 78e08d625..a9feb4570 100755 --- a/src/virt-manager.py.in +++ b/src/virt-manager.py.in @@ -211,55 +211,85 @@ def parse_commandline(): return optParser.parse_args() + def launch_specific_window(engine, show, uri, uuid): - if not engine.wait_for_open(uri): - # Connection failed, don't attempt to continue + logging.debug("Launching requested window '%s'" % show) + if show == 'creator': + engine.show_domain_creator(uri) + elif show == 'editor': + engine.show_domain_editor(uri, uuid) + elif show == 'performance': + engine.show_domain_performance(uri, uuid) + elif show == 'console': + engine.show_domain_console(uri, uuid) + elif show == 'summary': + engine.show_host_summary(uri) + +def _conn_state_changed(conn, engine, show, uri, uuid): + if conn.state == conn.STATE_DISCONNECTED: + return True + if conn.state != conn.STATE_ACTIVE: return - if show=='creator': - engine.show_create(uri) - elif show=='editor': - engine.show_details_config(uri, uuid) - elif show=='performance': - engine.show_details_performance(uri, uuid) - elif show=='console': - engine.show_console(uri, uuid) + + launch_specific_window(engine, show, uri, uuid) + return True # maps --show-* to engine (ie local instance) methods def show_engine(engine, show, uri, uuid, no_conn_auto): - if show=='creator' or show=='editor' \ - or show=='performance' or show=='console': - # Create a thread so we can wait for connection to _fully_ start, - # to prevent races accessing uninit'd vars for ex. the create wizard - # which expects the connection to be active. - thread = threading.Thread(target=launch_specific_window, - args=(engine, show, uri, uuid), - name="Launching '%s' window" % show) - thread.start() + conn = None + + # Do this regardless + engine.show_manager() + + if uri: + conn = engine.add_connection(uri) + + if conn and show: + import virtManager.util as util + util.connect_opt_out(conn, "state-changed", + _conn_state_changed, + engine, show, uri, uuid) - elif show=='summary' or uri: engine.connect_to_uri(uri) - else: - engine.show_manager() if not no_conn_auto: engine.autostart_connections() - # maps --show-* to remote manager (ie dbus call) methods def show_remote(managerObj, show, uri, uuid): - if show=='creator' or show=='editor' \ - or show=='performance' or show=='console': - # Create a thread so we can wait for connection to _fully_ start, - # to prevent races accessing uninit'd vars for ex. the create wizard - # which expects the connection to be active. - thread = threading.Thread(target=launch_specific_window, - args=(managerObj, show, uri, uuid), - name="Launching '%s' window" % show) - thread.start() - elif show=='summary' or uri: - managerObj.show_host_summary(uri) + # Do this regardless + managerObj.show_manager() + + if show or uri or uuid: + launch_specific_window(managerObj, show, uri, uuid) + +def dbus_config(engine): + """ + Setup dbus interface + """ + import dbus + from virtManager.remote import vmmRemote + bus = None + + if os.getenv("DBUS_STARTER_ADDRESS") is None: + bus = dbus.SessionBus() else: - managerObj.show_manager() + bus = dbus.StarterBus() + + dbusProxy = bus.get_object("org.freedesktop.DBus", "/org/freedesktop/DBus") + dbusObj = dbus.Interface(dbusProxy, "org.freedesktop.DBus") + + if dbusObj.NameHasOwner("com.redhat.virt.manager"): + # We're already running, so just talk to existing process + managerProxy = bus.get_object("com.redhat.virt.manager", + "/com/redhat/virt/manager") + managerObj = dbus.Interface(managerProxy, "com.redhat.virt.manager") + return managerObj + + else: + # Grab the service to allow others to talk to us later + name = dbus.service.BusName("com.redhat.virt.manager", bus=bus) + vmmRemote(engine, name) # Generic OptionParser callback for all --show-* options # This routine stores UUID to options.uuid for all --show-* options @@ -352,12 +382,11 @@ def main(): signal.signal(signal.SIGHUP, signal.SIG_IGN) from virtManager.engine import vmmEngine - from virtManager.remote import vmmRemote gtk.window_set_default_icon_from_file(icon_dir + "/" + appname + "-icon.svg") - if options.show and options.uri==None: + if options.show and options.uri == None: raise OptionValueError("can't use --show-* options without --connect") engine = vmmEngine(config) @@ -367,42 +396,18 @@ def main(): (os.getenv("DBUS_STARTER_ADDRESS") is None))): try: - bus = None - if os.getenv("DBUS_STARTER_ADDRESS") is None: - bus = dbus.SessionBus() - else: - bus = dbus.StarterBus() - - dbusProxy = bus.get_object("org.freedesktop.DBus", - "/org/freedesktop/DBus") - dbusObj = dbus.Interface(dbusProxy, "org.freedesktop.DBus") - - if dbusObj.NameHasOwner("com.redhat.virt.manager"): - # We're already running, so just talk to existing process - - managerProxy = bus.get_object("com.redhat.virt.manager", - "/com/redhat/virt/manager") - managerObj = dbus.Interface(managerProxy, - "com.redhat.virt.manager") - - show_remote(managerObj, options.show, - options.uri, options.uuid) - + managerObj = dbus_config(engine) + if managerObj: # yes, we exit completely now - remote service is in charge logging.debug("Connected to already running instance.") + show_remote(managerObj, options.show, + options.uri, options.uuid) return - - else: - # Grab the service to allow others to talk to us later - name = dbus.service.BusName("com.redhat.virt.manager", bus=bus) - vmmRemote(engine, name) - except: # Something went wrong doing dbus setup, just ignore & carry on - logging.warning("Could not get connection to session bus, " - "disabling DBus service " + - str(sys.exc_info()[0]) + " " + - str(sys.exc_info()[1])) + logging.exception("Could not get connection to session bus, " + "disabling DBus service") + # At this point we're either starting a brand new controlling instance, # or the dbus comms to existing instance has failed diff --git a/src/virtManager/connection.py b/src/virtManager/connection.py index 4cdcc5262..ab36dd734 100644 --- a/src/virtManager/connection.py +++ b/src/virtManager/connection.py @@ -107,8 +107,6 @@ class vmmConnection(gobject.GObject): self.engine = engine self.connectThread = None - self.connectThreadEvent = threading.Event() - self.connectThreadEvent.set() self.connectError = None self.uri = uri if self.uri is None or self.uri.lower() == "xen": @@ -846,7 +844,6 @@ class vmmConnection(gobject.GObject): self._change_state(self.STATE_CONNECTING) logging.debug("Scheduling background open thread for " + self.uri) - self.connectThreadEvent.clear() self.connectThread = threading.Thread(target = self._open_thread, name = "Connect %s" % self.uri) self.connectThread.setDaemon(True) @@ -1034,27 +1031,24 @@ class vmmConnection(gobject.GObject): def _open_notify(self): logging.debug("Notifying open result") - try: - util.safe_idle_add(util.idle_emit, self, "state-changed") + util.safe_idle_add(util.idle_emit, self, "state-changed") - if self.state == self.STATE_ACTIVE: - caps = self.get_capabilities_xml() - logging.debug("%s capabilities:\n%s" % - (self.get_uri(), caps)) + if self.state == self.STATE_ACTIVE: + caps = self.get_capabilities_xml() + logging.debug("%s capabilities:\n%s" % + (self.get_uri(), caps)) - self.tick() - # If VMs disappeared since the last time we connected to - # this uri, remove their gconf entries so we don't pollute - # the database - self.config.reconcile_vm_entries(self.get_uri(), - self.vms.keys()) + self.tick() + # If VMs disappeared since the last time we connected to + # this uri, remove their gconf entries so we don't pollute + # the database + self.config.reconcile_vm_entries(self.get_uri(), + self.vms.keys()) - if self.state == self.STATE_DISCONNECTED: - util.safe_idle_add(util.idle_emit, self, "connect-error", - self.connectError) - self.connectError = None - finally: - self.connectThreadEvent.set() + if self.state == self.STATE_DISCONNECTED: + util.safe_idle_add(util.idle_emit, self, "connect-error", + self.connectError) + self.connectError = None ####################### diff --git a/src/virtManager/engine.py b/src/virtManager/engine.py index abe97b1a7..76aedc1f0 100644 --- a/src/virtManager/engine.py +++ b/src/virtManager/engine.py @@ -491,15 +491,6 @@ class vmmEngine(gobject.GObject): logging.debug("Exiting app normally.") gtk.main_quit() - def wait_for_open(self, uri): - # Used to ensure connection fully starts before running - # ONLY CALL FROM WITHIN A THREAD - conn = self.connect_to_uri(uri) - conn.connectThreadEvent.wait() - if conn.state != conn.STATE_ACTIVE: - return False - return True - def add_connection(self, uri, readOnly=None, autoconnect=False): conn = vmmConnection(self.get_config(), uri, readOnly, self) self.connections[uri] = { @@ -768,30 +759,33 @@ class vmmEngine(gobject.GObject): def show_manager(self): self._do_show_manager(None) - def show_create(self, uri): - win = self._do_show_create(self.get_manager(), uri) - if not win: - return - win.show() + def show_connect(self): + self._do_show_connect(self.get_manager()) - def show_console(self, uri, uuid): + def show_host_summary(self, uri): + self._do_show_host(self.get_manager(), uri) + + def show_domain_creator(self, uri): + self._do_show_create(self.get_manager(), uri) + + def show_domain_console(self, uri, uuid): win = self._do_show_details(self.get_manager(), uri, uuid) if not win: return win.activate_console_page() - def show_details_performance(self, uri, uuid): - win = self._do_show_details(self.get_manager(), uri, uuid) - if not win: - return - win.activate_performance_page() - - def show_details_config(self, uri, uuid): + def show_domain_editor(self, uri, uuid): win = self._do_show_details(self.get_manager(), uri, uuid) if not win: return win.activate_config_page() + def show_domain_performance(self, uri, uuid): + win = self._do_show_details(self.get_manager(), uri, uuid) + if not win: + return + win.activate_performance_page() + ####################################### # Domain actions run/destroy/save ... # ####################################### diff --git a/src/virtManager/remote.py b/src/virtManager/remote.py index 435f19a13..0e6aaa698 100644 --- a/src/virtManager/remote.py +++ b/src/virtManager/remote.py @@ -28,23 +28,23 @@ class vmmRemote(dbus.service.Object): @dbus.service.method("com.redhat.virt.manager", in_signature="s") def show_domain_creator(self, uri): - self.engine.show_create(uri) + self.engine.show_domain_creator(str(uri)) @dbus.service.method("com.redhat.virt.manager", in_signature="ss") def show_domain_editor(self, uri, uuid): - self.engine.show_details_config(uri, uuid) + self.engine.show_domain_editor(str(uri), str(uuid)) @dbus.service.method("com.redhat.virt.manager", in_signature="ss") def show_domain_performance(self, uri, uuid): - self.engine.show_details_performance(uri, uuid) + self.engine.show_domain_performance(str(uri), str(uuid)) @dbus.service.method("com.redhat.virt.manager", in_signature="ss") def show_domain_console(self, uri, uuid): - self.engine.show_console(uri, uuid) + self.engine.show_domain_console(str(uri), str(uuid)) @dbus.service.method("com.redhat.virt.manager", in_signature="s") def show_host_summary(self, uri): - self.engine.show_host(uri) + self.engine.show_host_summary(str(uri)) @dbus.service.method("com.redhat.virt.manager", in_signature="") def show_manager(self):