Package x2go :: Module registry
[frames] | no frames]

Source Code for Module x2go.registry

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