Package x2go :: Module registry

[frames] | no frames]

# Source Code for Module x2go.registry

       1  # -*- coding: utf-8 -*-
       2
       3  # Copyright (C) 2010-2013 by Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
       4  #
       5  # Python X2Go is free software; you can redistribute it and/or modify
       6  # it under the terms of the GNU Affero General Public License as published by
       7  # the Free Software Foundation; either version 3 of the License, or
       8  # (at your option) any later version.
       9  #
      10  # Python X2Go is distributed in the hope that it will be useful,
      11  # but WITHOUT ANY WARRANTY; without even the implied warranty of
      12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13  # GNU Affero General Public License for more details.
      14  #
      15  # You should have received a copy of the GNU Affero General Public License
      16  # along with this program; if not, write to the
      17  # Free Software Foundation, Inc.,
      18  # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
      19
      20  """\
      21  X2GoSessionRegistry class - the X2GoClient's session registry backend
      22
      23  """
      24  __NAME__ = 'x2gosessregistry-pylib'
      25
      26  import os
      27  import copy
      28  import types
      29  import time
      30  import threading
      31  import re
      32
      33  # Python X2Go modules
      34  import log
      35  import utils
      36  import session
      37  import x2go_exceptions
      38
      39  # import the default terminal session backend
      40  from x2go.backends.control import X2GoControlSession as _X2GoControlSession
      41  from x2go.backends.terminal import X2GoTerminalSession as _X2GoTerminalSession
      42  from x2go.backends.info import X2GoServerSessionInfo as _X2GoServerSessionInfo
      43  from x2go.backends.info import X2GoServerSessionList as _X2GoServerSessionList
      44  from x2go.backends.proxy import X2GoProxy as _X2GoProxy
      45  from x2go.backends.settings import X2GoClientSettings as _X2GoClientSettings
      46  from x2go.backends.printing import X2GoClientPrinting as _X2GoClientPrinting
      47
      48  from defaults import LOCAL_HOME as _LOCAL_HOME
      49  from defaults import X2GO_CLIENT_ROOTDIR as _X2GO_CLIENT_ROOTDIR
      50  from defaults import X2GO_SESSIONS_ROOTDIR as _X2GO_SESSIONS_ROOTDIR
      51  from defaults import X2GO_SESSIONPROFILE_DEFAULTS as _X2GO_SESSIONPROFILE_DEFAULTS
      52  from defaults import X2GO_SSH_ROOTDIR as _X2GO_SSH_ROOTDIR
      53
      54 -class X2GoSessionRegistry(object):
      55      """\
      56      This class is utilized by L{X2GoClient} instances to maintain a good overview on
      57      session status of all associated L{X2GoSession} instances.
      58
      59      """
      60 -    def __init__(self, client_instance,
      61                   logger=None, loglevel=log.loglevel_DEFAULT):
      62          """\
      63          @param client_instance: the L{X2GoClient} instance that instantiated this L{X2GoSessionRegistry} instance.
      64          @type client_instance: L{X2GoClient} instance
      65          @param logger: you can pass an L{X2GoLogger} object to the L{X2GoClientXConfig} constructor
      66          @type logger: C{obj}
      67          @param loglevel: if no L{X2GoLogger} object has been supplied a new one will be
      68              constructed with the given loglevel
      69          @type loglevel: C{int}
      70
      71          """
      72          if logger is None:
      73              self.logger = log.X2GoLogger(loglevel=loglevel)
      74          else:
      75              self.logger = copy.deepcopy(logger)
      76          self.logger.tag = __NAME__
      77
      78          self.client_instance = client_instance
      79
      80          self.registry = {}
      81          self.control_sessions = {}
      82          self.master_sessions = {}
      83
      84          self._last_available_session_registration = None
      85          self._skip_auto_registration = False
      86          self._profile_locks = {}
      87
      88 -    def keys(self):
      89          """\
      90          A list of session registry keys.
      91
      92          @return: session registry key list
      93          @rtype: C{list}
      94
      95          """
      96          return self.registry.keys()
      97
      98 -    def __repr__(self):
      99          result = 'X2GoSessionRegistry('
     100          for p in dir(self):
     101              if '__' in p or not p in self.__dict__ or type(p) is types.InstanceType: continue
     102              result += p + '=' + str(self.__dict__[p]) + ','
     103          result = result.strip(',')
     104          return result + ')'
     105
     106 -    def __call__(self, session_uuid):
     107          """\
     108          Returns the L{X2GoSession} instance for a given session UUID hash.
     109
     110          @param session_uuid: the X2Go session's UUID registry hash
     111          @type session_uuid: C{str}
     112
     113          @return: the corresponding L{X2GoSession} instance
     114          @rtype: L{X2GoSession} instance
     115
     116          @raise X2GoSessionRegistryException: if the given session UUID could not be found
     117
     118          """
     119          try:
     120              return self.registry[session_uuid]
     121          except KeyError:
     122              raise x2go_exceptions.X2GoSessionRegistryException('No session found for UUID %s' % session_uuid)
     123
     124 -    def disable_session_auto_registration(self):
     125          """\
     126          This method is used to temporarily skip auto-registration of newly appearing
     127          X2Go session on the server side. This is necessary during session startups to
     128          assure that the session registry does not get filled with session UUID
     129          duplicates.
     130
     131          """
     132          self._skip_auto_registration = True
     133
     134 -    def enable_session_auto_registration(self):
     135          """\
     136          This method is used to temporarily (re-)enable auto-registration of newly appearing
     137          X2Go session on the server side.
     138
     139          """
     140          self._skip_auto_registration = False
     141
     142 -    def forget(self, session_uuid):
     143          """\
     144          Forget the complete record for session UUID C{session_uuid}.
     145
     146          @param session_uuid: the X2Go session's UUID registry hash
     147          @type session_uuid: C{str}
     148
     149          """
     150          try:
     151              del self.registry[session_uuid]
     152              self.logger('Forgetting session UUID %s' % session_uuid, loglevel=log.loglevel_DEBUG)
     153          except KeyError:
     154              pass
     155
     156 -    def get_profile_id(self, session_uuid):
     157          """\
     158          Retrieve the profile ID of a given session UUID hash.
     159
     160          @param session_uuid: the X2Go session's UUID registry hash
     161          @type session_uuid: C{str}
     162
     163          @return: profile ID
     164          @rtype: C{str}
     165
     166          """
     167          return self(session_uuid).get_profile_id()
     168
     169 -    def get_profile_name(self, session_uuid):
     170          """\
     171          Retrieve the profile name of a given session UUID hash.
     172
     173          @param session_uuid: the X2Go session's UUID registry hash
     174          @type session_uuid: C{str}
     175
     176          @return: profile name
     177          @rtype: C{str}
     178
     179          """
     180          return self(session_uuid).get_profile_name()
     181
     182 -    def session_summary(self, session_uuid, status_only=False):
     183          """\
     184          Compose a session summary (as Python dictionary).
     185
     186          @param session_uuid: the X2Go session's UUID registry hash
     187          @type session_uuid: C{str}
     188
     189          @return: session summary dictionary
     190          @rtype: C{dict}
     191
     192          """
     193          _session_summary = {}
     194          _r = False
     195          if session_uuid in [ s() for s in self.registered_sessions() ]:
     196              _r = True
     197
     198          if not status_only:
     199              _session_summary['uuid'] = _r and session_uuid or None
     200              _session_summary['profile_id'] = _r and self.get_profile_id(session_uuid) or ''
     201              _session_summary['profile_name'] = _r and self.get_profile_name(session_uuid) or ''
     202              _session_summary['session_name'] = _r and self(session_uuid).get_session_name() or ''
     203              _session_summary['control_session'] = _r and self(session_uuid).get_control_session() or None
     204              _session_summary['control_params'] = _r and self(session_uuid).control_params or {}
     205              _session_summary['terminal_session'] = _r and self(session_uuid).get_terminal_session() or None
     206              _session_summary['terminal_params'] = _r and self(session_uuid).terminal_params or {}
     207              _session_summary['active_threads'] = _r and bool(self(session_uuid).get_terminal_session()) and self(session_uuid).get_terminal_session().active_threads or []
     208              _session_summary['backends'] = {
     209                  'control': _r and self(session_uuid).control_backend or None,
     210                  'terminal': _r and self(session_uuid).terminal_backend or None,
     211                  'info': _r and self(session_uuid).info_backend or None,
     212                  'list': _r and self(session_uuid).list_backend or None,
     213                  'proxy': _r and self(session_uuid).proxy_backend or None,
     214              }
     215
     216          if _r:
     217              _session_summary['virgin'] = self(session_uuid).virgin
     218              _session_summary['connected'] = self(session_uuid).connected
     219              _session_summary['running'] = self(session_uuid).running
     220              _session_summary['suspended'] = self(session_uuid).suspended
     221              _session_summary['terminated'] = self(session_uuid).terminated
     222          else:
     223              _session_summary['virgin'] = None
     224              _session_summary['connected'] = None
     225              _session_summary['running'] = None
     226              _session_summary['suspended'] = None
     227              _session_summary['terminated'] = None
     228          return _session_summary
     229
     230 -    def update_status(self, session_uuid=None, profile_name=None, profile_id=None, session_list=None, force_update=False, newly_connected=False):
     231          """\
     232          Update the session status for L{X2GoSession} that is represented by a given session UUID hash,
     233          profile name or profile ID.
     234
     235          @param session_uuid: the X2Go session's UUID registry hash
     236          @type session_uuid: C{str}
     237          @param profile_name: alternatively, a profile name can be specified (the stati of all registered sessions for this session
     238              profile will be updated)
     239          @type profile_name: C{str}
     240          @param profile_id: alternatively, a profile ID can be given (the stati of all registered sessions for this session
     241              profile will be updated)
     242          @type profile_id: C{str}
     243          @param session_list: an optional C{X2GoServerSessionList*} instance (as returned by the L{X2GoClient.list_sessions()} command can
     244              be passed to this method.
     245          @type session_list: C{X2GoServerSessionList*} instance
     246          @param force_update: make sure the session status gets really updated
     247          @type force_update: C{bool}
     248
     249          @return: C{True} if this method has been successful
     250          @rtype: C{bool}
     251
     252          @raise X2GoSessionRegistryException: if the combination of C{session_uuid}, C{profile_name} and C{profile_id} does not match the requirement:
     253              only one of them
     254
     255          """
     256          if session_uuid and profile_name or session_uuid and profile_id or profile_name and profile_id:
     257              raise x2go_exceptions.X2GoSessionRegistryException('only one of the possible method parameters is allowed (session_uuid, profile_name or profile_id)')
     258          elif session_uuid is None and profile_name is None and profile_id is None:
     259              raise x2go_exceptions.X2GoSessionRegistryException('at least one of the method parameters session_uuid, profile_name or profile_id must be given')
     260
     261          if session_uuid:
     262              session_uuids = [ session_uuid ]
     263          elif profile_name:
     264              session_uuids = [ s() for s in self.registered_sessions_of_profile_name(profile_name, return_objects=True) ]
     265          elif profile_id:
     266              session_uuids = [ s() for s in self.registered_sessions_of_profile_name(self.client_instance.to_profile_name(profile_id), return_objects=True) ]
     267
     268          for _session_uuid in session_uuids:
     269
     270              # only operate on instantiated X2GoSession objects
     271              if type(self(_session_uuid)) != session.X2GoSession:
     272                  continue
     273
     274              if self(_session_uuid).is_locked():
     275                  continue
     276
     277              if not self(_session_uuid).update_status(session_list=session_list, force_update=force_update):
     278                  # skip this run, as nothing has changed since the last time...
     279                  continue
     280
     281              _last_status = copy.deepcopy(self(_session_uuid)._last_status)
     282              _current_status = copy.deepcopy(self(_session_uuid)._current_status)
     283
     284              # at this point we hook into the X2GoClient instance and call notification methods
     285              # that can be used to inform an application that something has happened
     286
     287              _profile_name = self(_session_uuid).get_profile_name()
     288              _session_name = self(_session_uuid).get_session_name()
     289
     290              if self(_session_uuid).get_server_hostname() != _current_status['server']:
     291
     292                  # if the server (hostname) has changed due to a configuration change we skip all notifications
     293                  self(_session_uuid).session_cleanup()
     294                  self(_session_uuid).__del__()
     295                  if len(self.virgin_sessions_of_profile_name(profile_name)) > 1:
     296                      del self.registry[_session_uuid]
     297
     298              elif not _last_status['running'] and _current_status['running'] and not _current_status['faulty']:
     299                  # session has started
     300                  if newly_connected:
     301                      # from a suspended state
     302                      self.client_instance.HOOK_on_found_session_running_after_connect(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name)
     303                  else:
     304                      # explicitly ask for the terminal_session object directly here, so we also get 'PENDING' terminal sessions here...
     305                      if self(_session_uuid).terminal_session:
     306
     307                          # declare as master session if appropriate
     308                          if _profile_name not in self.master_sessions.keys():
     309                              self.master_sessions[_profile_name] = self(_session_uuid)
     310                              self(_session_uuid).set_master_session()
     311
     312                          elif (not self.master_sessions[_profile_name].is_desktop_session() and self(_session_uuid).is_desktop_session()) or \
     313                               (not self.master_sessions[_profile_name].is_desktop_session() and self(_session_uuid).is_published_applications_provider()):
     314                                  self(self.master_sessions[_profile_name]()).unset_master_session()
     315                                  self.master_sessions[_profile_name] = self(_session_uuid)
     316                                  self(_session_uuid).set_master_session()
     317
     318                          if _last_status['suspended']:
     319                              # from a suspended state
     320                              self.client_instance.HOOK_on_session_has_resumed_by_me(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name)
     321                          elif _last_status['virgin']:
     322                              # as a new session
     323                              self.client_instance.HOOK_on_session_has_started_by_me(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name)
     324
     325                      else:
     326                          if _last_status['suspended']:
     327                              # from a suspended state
     328                              self.client_instance.HOOK_on_session_has_resumed_by_other(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name)
     329                          elif _last_status['connected'] and _last_status['virgin']:
     330                              # as a new session, do not report directly after connect due to many false positives then...
     331                              self.client_instance.HOOK_on_session_has_started_by_other(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name)
     332
     333              elif _last_status['connected'] and (not _last_status['suspended'] and _current_status['suspended']) and not _current_status['faulty'] and _session_name:
     334
     335                  # unregister as master session
     336                  if _profile_name in self.master_sessions.keys():
     337                      if self.master_sessions[_profile_name] == self(_session_uuid):
     338
     339                          self(_session_uuid).unset_master_session()
     340                          del self.master_sessions[_profile_name]
     341
     342                  # session has been suspended
     343                  self(_session_uuid).session_cleanup()
     344                  self.client_instance.HOOK_on_session_has_been_suspended(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name)
     345
     346              elif _last_status['connected'] and (not _last_status['terminated'] and _current_status['terminated']) and not _current_status['faulty'] and _session_name:
     347
     348                  # unregister as master session
     349                  if _profile_name in self.master_sessions.keys():
     350                      if self.master_sessions[_profile_name] == self(_session_uuid):
     351
     352                          self(_session_uuid).unset_master_session()
     353                          del self.master_sessions[_profile_name]
     354
     355                  # session has terminated
     356                  self.client_instance.HOOK_on_session_has_terminated(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name)
     357                  try: self(_session_uuid).session_cleanup()
     358                  except x2go_exceptions.X2GoSessionException: pass
     359                  try: self(_session_uuid).__del__()
     360                  except x2go_exceptions.X2GoSessionException: pass
     361                  if len(self.virgin_sessions_of_profile_name(profile_name)) > 1:
     362                      self.forget(_session_uuid)
     363
     364          # detect master sessions for connected profiles that have lost (suspend/terminate) their master session or never had a master session
     365          for _profile_name in [ p for p in self.connected_profiles(return_profile_names=True) if p not in self.master_sessions.keys() ]:
     366              _running_associated_sessions = [ _s for _s in self.running_sessions_of_profile_name(_profile_name, return_objects=True) if _s.is_associated() ]
     367              if _running_associated_sessions:
     368                  for _r_a_s in _running_associated_sessions:
     369                      if _r_a_s.is_desktop_session():
     370                          self.master_sessions[_profile_name] = _r_a_s
     371                          _r_a_s.set_master_session(wait=1)
     372                          break
     373                  if not self.master_sessions.has_key(_profile_name):
     374                      _pubapp_associated_sessions = self.pubapp_sessions_of_profile_name(_profile_name, return_objects=True)
     375                      if _pubapp_associated_sessions:
     376                          self.master_sessions[_profile_name] = _pubapp_associated_sessions[0]
     377                          _pubapp_associated_sessions[0].set_master_session(wait=2)
     378                      else:
     379                          self.master_sessions[_profile_name] = _running_associated_sessions[0]
     380                          _running_associated_sessions[0].set_master_session(wait=2)
     381
     382          return True
     383
     384 -    def register_available_server_sessions(self, profile_name, session_list=None, newly_connected=False, re_register=False, skip_pubapp_sessions=False):
     385          """\
     386          Register server-side available X2Go sessions with this L{X2GoSessionRegistry} instance for a given profile name.
     387
     388          @param profile_name: session profile name to register available X2Go sessions for
     389          @type profile_name: C{str}
     390          @param session_list: an optional C{X2GoServerSessionList*} instance (as returned by the L{X2GoClient.list_sessions()} command can
     391              be passed to this method.
     392          @type session_list: C{X2GoServerSessionList*} instance
     393          @param newly_connected: give a hint that the session profile got newly connected
     394          @type newly_connected: C{bool}
     395          @param re_register: re-register available sessions, needs to be done after changes to the session profile
     396          @type re_register: C{bool}
     397          @param skip_pubapp_sessions: Do not register published applications sessions
     398          @type skip_pubapp_sessions: C{bool}
     399
     400          """
     401          if self._last_available_session_registration is not None:
     402              _now = time.time()
     403              _time_delta = _now - self._last_available_session_registration
     404              if _time_delta < 2 and not re_register:
     405                  self.logger('registration interval too short (%s), skipping automatic session registration...' % _time_delta, loglevel=log.loglevel_DEBUG)
     406                  return
     407              self._last_available_session_registration = _now
     408
     409          _connected_sessions = self.connected_sessions_of_profile_name(profile_name=profile_name, return_objects=False)
     410          _registered_sessions = self.registered_sessions_of_profile_name(profile_name=profile_name, return_objects=False)
     411          _session_names = [ self(s_uuid).session_name for s_uuid in _registered_sessions if self(s_uuid).session_name is not None ]
     412
     413          if _connected_sessions:
     414              # any of the connected sessions is valuable for accessing the profile's control
     415              # session commands, so we simply take the first that comes in...
     416              _ctrl_session = self(_connected_sessions[0])
     417
     418              if session_list is None:
     419                  session_list = _ctrl_session.list_sessions()
     420
     421              # make sure the session registry gets updated before registering new session
     422              # (if the server name has changed, this will kick out obsolete X2GoSessions)
     423              self.update_status(profile_name=profile_name, session_list=session_list, force_update=True)
     424              for session_name in session_list.keys():
     425                  if (session_name not in _session_names and not self._skip_auto_registration) or re_register:
     426                      server = _ctrl_session.get_server_hostname()
     427                      profile_id = _ctrl_session.get_profile_id()
     428
     429                      # reconstruct all session options of _ctrl_session to auto-register a suspended session
     430                      # found on the _ctrl_session's connected server
     431                      _clone_kwargs = _ctrl_session.__dict__
     432                      kwargs = {}
     433                      kwargs.update(self.client_instance.session_profiles.to_session_params(profile_id))
     434                      kwargs['client_instance'] = self.client_instance
     435                      kwargs['control_backend'] = _clone_kwargs['control_backend']
     436                      kwargs['terminal_backend'] = _clone_kwargs['terminal_backend']
     437                      kwargs['proxy_backend'] = _clone_kwargs['proxy_backend']
     438                      kwargs['info_backend'] = _clone_kwargs['info_backend']
     439                      kwargs['list_backend'] = _clone_kwargs['list_backend']
     440                      kwargs['settings_backend'] = _clone_kwargs['settings_backend']
     441                      kwargs['printing_backend'] = _clone_kwargs['printing_backend']
     442                      kwargs['keep_controlsession_alive'] = _clone_kwargs['keep_controlsession_alive']
     443                      kwargs['client_rootdir'] = _clone_kwargs['client_rootdir']
     444                      kwargs['sessions_rootdir'] = _clone_kwargs['sessions_rootdir']
     445
     446                      try: del kwargs['server']
     447                      except: pass
     448                      try: del kwargs['profile_name']
     449                      except: pass
     450                      try: del kwargs['profile_id']
     451                      except: pass
     452
     453                      # this if clause catches problems when x2golistsessions commands give weird results
     454                      if not self.has_session_of_session_name(session_name) or re_register:
     455                          if not (skip_pubapp_sessions and re.match('.*_stRPUBLISHED_.*', session_name)):
     456                              session_uuid = self.register(server, profile_id, profile_name,
     457                                                           session_name=session_name, virgin=False,
     458                                                           **kwargs
     459                                                          )
     460                              self(session_uuid).connected = True
     461                              self.update_status(session_uuid=session_uuid, force_update=True, newly_connected=newly_connected)
     462
     463 -    def register(self, server, profile_id, profile_name,
     464                   session_name=None,
     465                   control_backend=_X2GoControlSession,
     466                   terminal_backend=_X2GoTerminalSession,
     467                   info_backend=_X2GoServerSessionInfo,
     468                   list_backend=_X2GoServerSessionList,
     469                   proxy_backend=_X2GoProxy,
     470                   settings_backend=_X2GoClientSettings,
     471                   printing_backend=_X2GoClientPrinting,
     472                   client_rootdir=os.path.join(_LOCAL_HOME,_X2GO_CLIENT_ROOTDIR),
     473                   sessions_rootdir=os.path.join(_LOCAL_HOME,_X2GO_SESSIONS_ROOTDIR),
     474                   ssh_rootdir=os.path.join(_LOCAL_HOME,_X2GO_SSH_ROOTDIR),
     475                   keep_controlsession_alive=True,
     476                   add_to_known_hosts=False,
     477                   known_hosts=None,
     478                   **kwargs):
     479          """\
     480          Register a new L{X2GoSession} instance with this L{X2GoSessionRegistry}.
     481
     482          @param server: hostname of X2Go server
     483          @type server: C{str}
     484          @param profile_id: profile ID
     485          @type profile_id: C{str}
     486          @param profile_name: profile name
     487          @type profile_name: C{str}
     488          @param session_name: session name (if available)
     489          @type session_name: C{str}
     490          @param control_backend: X2Go control session backend to use
     491          @type control_backend: C{class}
     492          @param terminal_backend: X2Go terminal session backend to use
     493          @type terminal_backend: C{class}
     494          @param info_backend: X2Go session info backend to use
     495          @type info_backend: C{class}
     496          @param list_backend: X2Go session list backend to use
     497          @type list_backend: C{class}
     498          @param proxy_backend: X2Go proxy backend to use
     499          @type proxy_backend: C{class}
     500          @param settings_backend: X2Go client settings backend to use
     501          @type settings_backend: C{class}
     502          @param printing_backend: X2Go client printing backend to use
     503          @type printing_backend: C{class}
     504          @param client_rootdir: client base dir (default: ~/.x2goclient)
     505          @type client_rootdir: C{str}
     506          @param sessions_rootdir: sessions base dir (default: ~/.x2go)
     507          @type sessions_rootdir: C{str}
     508          @param ssh_rootdir: ssh base dir (default: ~/.ssh)
     509          @type ssh_rootdir: C{str}
     510          @param keep_controlsession_alive: On last L{X2GoSession.disconnect()} keep the associated C{X2GoControlSession*} instance alive?
     511          @ŧype keep_controlsession_alive: C{bool}
     512          @param add_to_known_hosts: Auto-accept server host validity?
     513          @type add_to_known_hosts: C{bool}
     514          @param known_hosts: the underlying Paramiko/SSH systems C{known_hosts} file
     515          @type known_hosts: C{str}
     516          @param kwargs: all other options will be passed on to the constructor of the to-be-instantiated L{X2GoSession} instance
     517          @type C{dict}
     518
     519          @return: the session UUID of the newly registered (or re-registered) session
     520          @rtype: C{str}
     521
     522          """
     523          if profile_id not in self._profile_locks.keys():
     524              self._profile_locks[profile_id] = threading.Lock()
     525
     526          self._profile_locks[profile_id].acquire()
     527
     528          control_session = None
     529          if profile_id in self.control_sessions.keys():
     530              control_session = self.control_sessions[profile_id]
     531
     532          try:
     533              _params = self.client_instance.session_profiles.to_session_params(profile_id)
     534
     535          except x2go_exceptions.X2GoProfileException:
     536              _params = utils._convert_SessionProfileOptions_2_SessionParams(_X2GO_SESSIONPROFILE_DEFAULTS)
     537
     538          for _k in _params.keys():
     539              if _k in kwargs.keys():
     540                  _params[_k] = kwargs[_k]
     541
     542          # when starting a new session, we will try to use unused registered virgin sessions
     543          # depending on your application layout, there should either be one or no such virgin session at all
     544          _virgin_sessions = [ s for s in self.virgin_sessions_of_profile_name(profile_name, return_objects=True) if not s.activated ]
     545          if _virgin_sessions and not session_name:
     546              session_uuid = _virgin_sessions[0].get_uuid()
     547              self(session_uuid).activated = True
     548              self.logger('using already initially-registered yet-unused session %s' % session_uuid, loglevel=log.loglevel_NOTICE)
     549
     550          else:
     551              session_uuid = self.get_session_of_session_name(session_name, match_profile_name=profile_name)
     552              if session_uuid is not None: self.logger('using already registered-by-session-name session %s' % session_uuid, loglevel=log.loglevel_NOTICE)
     553
     554          if session_uuid is not None:
     555              self(session_uuid).activated = True
     556              self(session_uuid).update_params(_params)
     557              self(session_uuid).set_server(server)
     558              self(session_uuid).set_profile_name(profile_name)
     559              self._profile_locks[profile_id].release()
     560              return session_uuid
     561
     562          try: del _params['server']
     563          except: pass
     564          try: del _params['profile_name']
     565          except: pass
     566          try: del _params['profile_id']
     567          except: pass
     568
     569          s = session.X2GoSession(server=server, control_session=control_session,
     570                                  profile_id=profile_id, profile_name=profile_name,
     571                                  session_name=session_name,
     572                                  control_backend=control_backend,
     573                                  terminal_backend=terminal_backend,
     574                                  info_backend=info_backend,
     575                                  list_backend=list_backend,
     576                                  proxy_backend=proxy_backend,
     577                                  settings_backend=settings_backend,
     578                                  printing_backend=printing_backend,
     579                                  client_rootdir=client_rootdir,
     580                                  sessions_rootdir=sessions_rootdir,
     581                                  ssh_rootdir=ssh_rootdir,
     582                                  keep_controlsession_alive=keep_controlsession_alive,
     583                                  add_to_known_hosts=add_to_known_hosts,
     584                                  known_hosts=known_hosts,
     585                                  client_instance=self.client_instance,
     586                                  logger=self.logger, **_params)
     587
     588          session_uuid = s._X2GoSession__get_uuid()
     589          self.logger('registering X2Go session %s...' % profile_name, log.loglevel_NOTICE)
     590          self.logger('registering X2Go session with UUID %s' % session_uuid, log.loglevel_DEBUG)
     591
     592          self.registry[session_uuid] = s
     593          if profile_id not in self.control_sessions.keys():
     594              self.control_sessions[profile_id] = s.get_control_session()
     595
     596          # make sure a new session is a non-master session unless promoted in update_status method
     597          self(session_uuid).unset_master_session()
     598          if control_session is None:
     599              self(session_uuid).do_auto_connect()
     600
     601          self._profile_locks[profile_id].release()
     602          return session_uuid
     603
     604 -    def has_session_of_session_name(self, session_name, match_profile_name=None):
     605          """\
     606          Detect if we know about an L{X2GoSession} of name C{<session_name>}.
     607
     608          @param session_name: name of session to be searched for
     609          @type session_name: C{str}
     610          @param match_profile_name: a session's profile_name must match this profile name
     611          @type match_profile_name: C{str}
     612
     613          @return: C{True} if a session of C{<session_name>} has been found
     614          @rtype: C{bool}
     615
     616          """
     617          return bool(self.get_session_of_session_name(session_name, match_profile_name=match_profile_name))
     618
     619 -    def get_session_of_session_name(self, session_name, return_object=False, match_profile_name=None):
     620          """\
     621          Retrieve the L{X2GoSession} instance with session name C{<session_name>}.
     622
     623          @param session_name: name of session to be retrieved
     624          @type session_name: C{str}
     625          @param return_object: if C{False} the session UUID hash will be returned, if C{True} the L{X2GoSession} instance will be returned
     626          @type return_object: C{bool}
     627          @param match_profile_name: returned sessions must match this profile name
     628          @type match_profile_name: C{str}
     629
     630          @return: L{X2GoSession} object or its representing session UUID hash
     631          @rtype: L{X2GoSession} instance or C{str}
     632
     633          @raise X2GoSessionRegistryException: if there is more than one L{X2GoSession} registered for C{<session_name>} within
     634              the same L{X2GoClient} instance. This should never happen!
     635
     636          """
     637          if match_profile_name is None:
     638              reg_sessions = self.registered_sessions()
     639          else:
     640              reg_sessions = self.registered_sessions_of_profile_name(match_profile_name)
     641          found_sessions = [ s for s in reg_sessions if s.session_name == session_name and s.session_name is not None ]
     642          if len(found_sessions) == 1:
     643              session = found_sessions[0]
     644              if return_object:
     645                  return session
     646              else:
     647                  return session.get_uuid()
     648          elif len(found_sessions) > 1:
     649              raise x2go_exceptions.X2GoSessionRegistryException('there should only be one registered session of name ,,%s\'\'' % session_name)
     650          else:
     651              return None
     652
     653 -    def _sessionsWithState(self, state, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
     654          if state == 'associated':
     655              sessions = [ ts for ts in self.registry.values() if ts.has_terminal_session() ]
     656          elif state == 'registered':
     657              sessions = [ ts for ts in self.registry.values() ]
     658          else:
     659              sessions = [ ts for ts in self.registry.values() if eval('ts.%s' % state) ]
     660          if return_profile_names:
     661              profile_names = []
     662              for session in sessions:
     663                  if session.profile_name not in profile_names:
     664                      profile_names.append(session.profile_name)
     665              return profile_names
     666          elif return_profile_ids:
     667              profile_ids = []
     668              for session in sessions:
     669                  if session.profile_id not in profile_ids:
     670                      profile_ids.append(session.profile_id)
     671              return profile_ids
     672          elif return_session_names:
     673              session_names = []
     674              for session in sessions:
     675                  if session.session_name not in session_names:
     676                      session_names.append(session.session_name)
     677              return session_names
     678          elif return_objects:
     679              return sessions
     680          else:
     681              return [s.get_uuid() for s in sessions ]
     682
     683 -    def connected_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
     684          """\
     685          Retrieve a list of sessions that the underlying L{X2GoClient} instances is currently connected to.
     686          If none of the C{return_*} options is specified a list of session UUID hashes will be returned.
     687
     688          @param return_objects: return as list of L{X2GoSession} instances
     689          @type return_objects: C{bool}
     690          @param return_profile_names: return as list of profile names
     691          @type return_profile_names: C{bool}
     692          @param return_profile_ids: return as list of profile IDs
     693          @type return_profile_ids: C{bool}
     694          @param return_session_names: return as list of X2Go session names
     695          @type return_session_names: C{bool}
     696
     697          @return: a session list (as UUID hashes, objects, profile names/IDs or session names)
     698          @rtype: C{list}
     699
     700          """
     701          return self._sessionsWithState('connected', return_objects=return_objects, return_profile_names=return_profile_names, return_profile_ids=return_profile_ids, return_session_names=return_session_names)
     702
     703 -    def associated_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
     704          """\
     705          Retrieve a list of sessions that are currently associated by an C{X2GoTerminalSession*} to the underlying L{X2GoClient} instance.
     706          If none of the C{return_*} options is specified a list of session UUID hashes will be returned.
     707
     708          @param return_objects: return as list of L{X2GoSession} instances
     709          @type return_objects: C{bool}
     710          @param return_profile_names: return as list of profile names
     711          @type return_profile_names: C{bool}
     712          @param return_profile_ids: return as list of profile IDs
     713          @type return_profile_ids: C{bool}
     714          @param return_session_names: return as list of X2Go session names
     715          @type return_session_names: C{bool}
     716
     717          @return: a session list (as UUID hashes, objects, profile names/IDs or session names)
     718          @rtype: C{list}
     719
     720          """
     721          return self._sessionsWithState('associated', return_objects=return_objects, return_profile_names=return_profile_names, return_profile_ids=return_profile_ids, return_session_names=return_session_names)
     722
     723 -    def virgin_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
     724          """\
     725          Retrieve a list of sessions that are currently still in virgin state (not yet connected, associated etc.).
     726          If none of the C{return_*} options is specified a list of session UUID hashes will be returned.
     727
     728          @param return_objects: return as list of L{X2GoSession} instances
     729          @type return_objects: C{bool}
     730          @param return_profile_names: return as list of profile names
     731          @type return_profile_names: C{bool}
     732          @param return_profile_ids: return as list of profile IDs
     733          @type return_profile_ids: C{bool}
     734          @param return_session_names: return as list of X2Go session names
     735          @type return_session_names: C{bool}
     736
     737          @return: a session list (as UUID hashes, objects, profile names/IDs or session names)
     738          @rtype: C{list}
     739
     740          """
     741          return self._sessionsWithState('virgin', return_objects=return_objects, return_profile_names=return_profile_names, return_profile_ids=return_profile_ids, return_session_names=return_session_names)
     742
     743 -    def running_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
     744          """\
     745          Retrieve a list of sessions that are currently in running state.
     746          If none of the C{return_*} options is specified a list of session UUID hashes will be returned.
     747
     748          @param return_objects: return as list of L{X2GoSession} instances
     749          @type return_objects: C{bool}
     750          @param return_profile_names: return as list of profile names
     751          @type return_profile_names: C{bool}
     752          @param return_profile_ids: return as list of profile IDs
     753          @type return_profile_ids: C{bool}
     754          @param return_session_names: return as list of X2Go session names
     755          @type return_session_names: C{bool}
     756
     757          @return: a session list (as UUID hashes, objects, profile names/IDs or session names)
     758          @rtype: C{list}
     759
     760          """
     761          return self._sessionsWithState('running', return_objects=return_objects, return_profile_names=return_profile_names, return_profile_ids=return_profile_ids, return_session_names=return_session_names)
     762
     763 -    def suspended_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
     764          """\
     765          Retrieve a list of sessions that are currently in suspended state.
     766          If none of the C{return_*} options is specified a list of session UUID hashes will be returned.
     767
     768          @param return_objects: return as list of L{X2GoSession} instances
     769          @type return_objects: C{bool}
     770          @param return_profile_names: return as list of profile names
     771          @type return_profile_names: C{bool}
     772          @param return_profile_ids: return as list of profile IDs
     773          @type return_profile_ids: C{bool}
     774          @param return_session_names: return as list of X2Go session names
     775          @type return_session_names: C{bool}
     776
     777          @return: a session list (as UUID hashes, objects, profile names/IDs or session names)
     778          @rtype: C{list}
     779
     780          """
     781          return self._sessionsWithState('suspended', return_objects=return_objects, return_profile_names=return_profile_names, return_profile_ids=return_profile_ids, return_session_names=return_session_names)
     782
     783 -    def terminated_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
     784          """\
     785          Retrieve a list of sessions that have terminated recently.
     786          If none of the C{return_*} options is specified a list of session UUID hashes will be returned.
     787
     788          @param return_objects: return as list of L{X2GoSession} instances
     789          @type return_objects: C{bool}
     790          @param return_profile_names: return as list of profile names
     791          @type return_profile_names: C{bool}
     792          @param return_profile_ids: return as list of profile IDs
     793          @type return_profile_ids: C{bool}
     794          @param return_session_names: return as list of X2Go session names
     795          @type return_session_names: C{bool}
     796
     797          @return: a session list (as UUID hashes, objects, profile names/IDs or session names)
     798          @rtype: C{list}
     799
     800          """
     801          return self._sessionsWithState('terminated', return_objects=return_objects, return_profile_names=return_profile_names, return_profile_ids=return_profile_ids, return_session_names=return_session_names)
     802
     803      @property
     804 -    def has_running_sessions(self):
     805          """\
     806          Equals C{True} if the underlying L{X2GoClient} instance has any running sessions at hand.
     807
     808          """
     809          return self.running_sessions() and len(self.running_sessions()) > 0
     810
     811      @property
     812 -    def has_suspended_sessions(self):
     813          """\
     814          Equals C{True} if the underlying L{X2GoClient} instance has any suspended sessions at hand.
     815
     816          """
     817          return self.suspended_sessions and len(self.suspended_sessions) > 0
     818
     819 -    def registered_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
     820          """\
     821          Retrieve a list of all registered sessions.
     822          If none of the C{return_*} options is specified a list of session UUID hashes will be returned.
     823
     824          @param return_objects: return as list of L{X2GoSession} instances
     825          @type return_objects: C{bool}
     826          @param return_profile_names: return as list of profile names
     827          @type return_profile_names: C{bool}
     828          @param return_profile_ids: return as list of profile IDs
     829          @type return_profile_ids: C{bool}
     830          @param return_session_names: return as list of X2Go session names
     831          @type return_session_names: C{bool}
     832
     833          @return: a session list (as UUID hashes, objects, profile names/IDs or session names)
     834          @rtype: C{list}
     835
     836          """
     837          return self._sessionsWithState('registered', return_objects=return_objects, return_profile_names=return_profile_names, return_profile_ids=return_profile_ids, return_session_names=return_session_names)
     838
     839 -    def non_running_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
     840          """\
     841          Retrieve a list of sessions that are currently _NOT_ in running state.
     842          If none of the C{return_*} options is specified a list of session UUID hashes will be returned.
     843
     844          @param return_objects: return as list of L{X2GoSession} instances
     845          @type return_objects: C{bool}
     846          @param return_profile_names: return as list of profile names
     847          @type return_profile_names: C{bool}
     848          @param return_profile_ids: return as list of profile IDs
     849          @type return_profile_ids: C{bool}
     850          @param return_session_names: return as list of X2Go session names
     851          @type return_session_names: C{bool}
     852
     853          @return: a session list (as UUID hashes, objects, profile names/IDs or session names)
     854          @rtype: C{list}
     855
     856          """
     857          return [ s for s in self.registered_sessions(return_objects=return_objects, return_profile_names=return_profile_names, return_profile_ids=return_profile_ids, return_session_names=return_session_names) if s not in self.running_sessions(return_objects=return_objects, return_profile_names=return_profile_names, return_profile_ids=return_profile_ids, return_session_names=return_session_names) ]
     858
     859 -    def connected_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
     860          """\
     861          For a given session profile name retrieve a list of sessions that are currently connected to the profile's X2Go server.
     862          If none of the C{return_*} options is specified a list of session UUID hashes will be returned.
     863
     864          @param profile_name: session profile name
     865          @type profile_name: C{str}
     866          @param return_objects: return as list of L{X2GoSession} instances
     867          @type return_objects: C{bool}
     868          @param return_session_names: return as list of X2Go session names
     869          @type return_session_names: C{bool}
     870
     871          @return: a session list (as UUID hashes, objects or session names)
     872          @rtype: C{list}
     873
     874          """
     875          if return_objects:
     876              return self.connected_sessions() and [ s for s in self.connected_sessions() if s.get_profile_name() == profile_name ]
     877          elif return_session_names:
     878              return self.connected_sessions() and [ s.session_name for s in self.connected_sessions() if s.get_profile_name() == profile_name ]
     879          else:
     880              return self.connected_sessions() and [ s.get_uuid() for s in self.connected_sessions() if s.get_profile_name() == profile_name ]
     881
     882 -    def associated_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
     883          """\
     884          For a given session profile name retrieve a list of sessions that are currently associated by an C{X2GoTerminalSession*} to this L{X2GoClient} instance.
     885          If none of the C{return_*} options is specified a list of session UUID hashes will be returned.
     886
     887          @param profile_name: session profile name
     888          @type profile_name: C{str}
     889          @param return_objects: return as list of L{X2GoSession} instances
     890          @type return_objects: C{bool}
     891          @param return_session_names: return as list of X2Go session names
     892          @type return_session_names: C{bool}
     893
     894          @return: a session list (as UUID hashes, objects or session names)
     895          @rtype: C{list}
     896
     897          """
     898          if return_objects:
     899              return self.associated_sessions() and [ s for s in self.associated_sessions() if s.get_profile_name() == profile_name ]
     900          elif return_session_names:
     901              return self.associated_sessions() and [ s.session_name for s in self.associated_sessions() if s.get_profile_name() == profile_name ]
     902          else:
     903              return self.associated_sessions() and [ s.get_uuid() for s in self.associated_sessions() if s.get_profile_name() == profile_name ]
     904
     905 -    def pubapp_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
     906          """\
     907          For a given session profile name retrieve a list of sessions that can be providers for published application list.
     908          If none of the C{return_*} options is specified a list of session UUID hashes will be returned.
     909
     910          @param profile_name: session profile name
     911          @type profile_name: C{str}
     912          @param return_objects: return as list of L{X2GoSession} instances
     913          @type return_objects: C{bool}
     914          @param return_session_names: return as list of X2Go session names
     915          @type return_session_names: C{bool}
     916
     917          @return: a session list (as UUID hashes, objects or session names)
     918          @rtype: C{list}
     919
     920          """
     921          if return_objects:
     922              return self.associated_sessions_of_profile_name(profile_name) and [ s for s in self.associated_sessions_of_profile_name(profile_name) if s.is_published_applications_provider() ]
     923          elif return_session_names:
     924              return self.associated_sessions_of_profile_name(profile_name) and [ s.session_name for s in self.associated_sessions_of_profile_name(profile_name) if s.is_published_applications_provider() ]
     925          else:
     926              return self.associated_sessions_of_profile_name(profile_name) and [ s.get_uuid() for s in self.associated_sessions_of_profile_name(profile_name) if s.is_published_applications_provider() ]
     927
     928 -    def registered_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
     929          """\
     930          For a given session profile name retrieve a list of sessions that are currently registered with this L{X2GoClient} instance.
     931          If none of the C{return_*} options is specified a list of session UUID hashes will be returned.
     932
     933          @param profile_name: session profile name
     934          @type profile_name: C{str}
     935          @param return_objects: return as list of L{X2GoSession} instances
     936          @type return_objects: C{bool}
     937          @param return_session_names: return as list of X2Go session names
     938          @type return_session_names: C{bool}
     939
     940          @return: a session list (as UUID hashes, objects or session names)
     941          @rtype: C{list}
     942
     943          """
     944          if return_objects:
     945              return self.registered_sessions() and [ s for s in self.registered_sessions() if s.get_profile_name() == profile_name ]
     946          elif return_session_names:
     947              return self.registered_sessions() and [ s.session_name for s in self.registered_sessions() if s.get_profile_name() == profile_name ]
     948          else:
     949              return self.registered_sessions() and [ s.get_uuid() for s in self.registered_sessions() if s.get_profile_name() == profile_name ]
     950
     951 -    def virgin_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
     952          """\
     953          For a given session profile name retrieve a list of sessions that are registered with this L{X2GoClient} instance but have not
     954          yet been started (i.e. sessions that are in virgin state). If none of the C{return_*} options is specified a list of
     955          session UUID hashes will be returned.
     956
     957          @param profile_name: session profile name
     958          @type profile_name: C{str}
     959          @param return_objects: return as list of L{X2GoSession} instances
     960          @type return_objects: C{bool}
     961          @param return_session_names: return as list of X2Go session names
     962          @type return_session_names: C{bool}
     963
     964          @return: a session list (as UUID hashes, objects or session names)
     965          @rtype: C{list}
     966
     967          """
     968          if return_objects:
     969              return self.virgin_sessions() and [ s for s in self.virgin_sessions() if s.get_profile_name() == profile_name ]
     970          elif return_session_names:
     971              return self.virgin_sessions() and [ s.session_name for s in self.virgin_sessions() if s.get_profile_name() == profile_name ]
     972          else:
     973              return self.virgin_sessions() and [ s.get_uuid() for s in self.virgin_sessions() if s.get_profile_name() == profile_name ]
     974
     975 -    def running_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
     976          """\
     977          For a given session profile name retrieve a list of sessions that are currently running.
     978          If none of the C{return_*} options is specified a list of session UUID hashes will be returned.
     979
     980          @param profile_name: session profile name
     981          @type profile_name: C{str}
     982          @param return_objects: return as list of L{X2GoSession} instances
     983          @type return_objects: C{bool}
     984          @param return_session_names: return as list of X2Go session names
     985          @type return_session_names: C{bool}
     986
     987          @return: a session list (as UUID hashes, objects or session names)
     988          @rtype: C{list}
     989
     990          """
     991          if return_objects:
     992              return self.running_sessions() and [ s for s in self.running_sessions() if s.get_profile_name() == profile_name ]
     993          elif return_session_names:
     994              return self.running_sessions() and [ s.session_name for s in self.running_sessions() if s.get_profile_name() == profile_name ]
     995          else:
     996              return self.running_sessions() and [ s.get_uuid() for s in self.running_sessions() if s.get_profile_name() == profile_name ]
     997
     998 -    def suspended_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
     999          """\
    1000          For a given session profile name retrieve a list of sessions that are currently in suspended state.
    1001          If none of the C{return_*} options is specified a list of session UUID hashes will be returned.
    1002
    1003          @param profile_name: session profile name
    1004          @type profile_name: C{str}
    1005          @param return_objects: return as list of L{X2GoSession} instances
    1006          @type return_objects: C{bool}
    1007          @param return_session_names: return as list of X2Go session names
    1008          @type return_session_names: C{bool}
    1009
    1010          @return: a session list (as UUID hashes, objects or session names)
    1011          @rtype: C{list}
    1012
    1013          """
    1014          if return_objects:
    1015              return self.suspended_sessions() and [ s for s in self.suspended_sessions() if s.get_profile_name() == profile_name ]
    1016          elif return_session_names:
    1017              return self.suspended_sessions() and [ s.session_name for s in self.suspended_sessions() if s.get_profile_name() == profile_name ]
    1018          else:
    1019              return self.suspended_sessions() and [ s.get_uuid() for s in self.suspended_sessions() if s.get_profile_name() == profile_name ]
    1020
    1021 -    def control_session_of_profile_name(self, profile_name):
    1022          """\
    1023          For a given session profile name retrieve a the corresponding C{X2GoControlSession*} instance.
    1024
    1025          @param profile_name: session profile name
    1026          @type profile_name: C{str}
    1027
    1028          @return: contol session instance
    1029          @rtype: C{X2GoControlSession*} instance
    1030
    1031          """
    1032          _sessions = self.registered_sessions_of_profile_name(profile_name, return_objects=True)
    1033          if _sessions:
    1034              session = _sessions[0]
    1035              return session.control_session
    1036          return None
    1037
    1038      @property
    1039 -    def connected_control_sessions(self):
    1040          """\
    1041          Equals a list of all currently connected control sessions.
    1042
    1043          """
    1044          return [ c for c in self.control_sessions.values() if c.is_connected() ]
    1045
    1046 -    def connected_profiles(self, use_paramiko=False, return_profile_ids=True, return_profile_names=False):
    1047          """\
    1048          Retrieve a list of all currently connected session profiles.
    1049
    1050          @param use_paramiko: send query directly to the Paramiko/SSH layer
    1051          @type use_paramiko: C{bool}
    1052
    1053          @return: list of connected session profiles
    1054          @rtype: C{list}
    1055
    1056          """
    1057          if use_paramiko:
    1058              return [ p for p in self.control_sessions.keys() if self.control_sessions[p].is_connected() ]
    1059          else:
    1060              return self.connected_sessions(return_profile_ids=return_profile_ids, return_profile_names=return_profile_names)
    1061
    1062 -    def get_master_session(self, profile_name, return_object=True, return_session_name=False):
    1063          """\
    1064          Retrieve the master session of a specific profile.
    1065
    1066          @param profile_name: the profile name that we query the master session of
    1067          @type profile_name: C{str}
    1068          @param return_object: return L{X2GoSession} instance
    1069          @type return_object: C{bool}
    1070          @param return_session_name: return X2Go session name
    1071          @type return_session_name: C{bool}
    1072
    1073          @return: a session list (as UUID hashes, objects, profile names/IDs or session names)
    1074          @rtype: C{list}
    1075
    1076          """
    1077          if profile_name not in self.connected_profiles(return_profile_names=True):
    1078              return None
    1079
    1080          if profile_name not in self.master_sessions.keys() or self.master_sessions[profile_name] is None:
    1081              return None
    1082
    1083          _session = self.master_sessions[profile_name]
    1084
    1085          if not _session.is_master_session():
    1086              del self.master_sessions[profile_name]
    1087              return None
    1088
    1089          if return_object:
    1090              return _session
    1091          elif return_session_name:
    1092              return _session.get_session_name()
    1093          else:
    1094              return _session.get_uuid()
    1095