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  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
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
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 not self(_session_uuid).update_status(session_list=session_list, force_update=force_update): 275 # skip this run, as nothing has changed since the last time... 276 continue 277 278 _last_status = copy.deepcopy(self(_session_uuid)._last_status) 279 _current_status = copy.deepcopy(self(_session_uuid)._current_status) 280 281 # at this point we hook into the X2goClient instance and call notification methods 282 # that can be used to inform an application that something has happened 283 284 _profile_name = self(_session_uuid).get_profile_name() 285 _session_name = self(_session_uuid).get_session_name() 286 287 if self(_session_uuid).get_server_hostname() != _current_status['server']: 288 289 # if the server (hostname) has changed due to a configuration change we skip all notifications 290 self(_session_uuid).session_cleanup() 291 self(_session_uuid).__del__() 292 if len(self.virgin_sessions_of_profile_name(profile_name)) > 1: 293 del self.registry[_session_uuid] 294 295 elif not _last_status['running'] and _current_status['running'] and not _current_status['faulty']: 296 # session has started 297 if newly_connected: 298 # from a suspended state 299 self.client_instance.HOOK_on_found_session_running_after_connect(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name) 300 else: 301 # explicitly ask for the terminal_session object directly here, so we also get 'PENDING' terminal sessions here... 302 if self(_session_uuid).terminal_session: 303 304 # declare as master session if appropriate 305 if _profile_name not in self.master_sessions.keys(): 306 self.master_sessions[_profile_name] = self(_session_uuid) 307 self(_session_uuid).set_master_session() 308 309 elif (not self.master_sessions[_profile_name].is_desktop_session() and self(_session_uuid).is_desktop_session()) or \ 310 (not self.master_sessions[_profile_name].is_desktop_session() and self(_session_uuid).is_published_applications_provider()): 311 self(self.master_sessions[_profile_name]()).unset_master_session() 312 self.master_sessions[_profile_name] = self(_session_uuid) 313 self(_session_uuid).set_master_session() 314 315 if _last_status['suspended']: 316 # from a suspended state 317 self.client_instance.HOOK_on_session_has_resumed_by_me(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name) 318 elif _last_status['virgin']: 319 # as a new session 320 self.client_instance.HOOK_on_session_has_started_by_me(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name) 321 322 else: 323 if _last_status['suspended']: 324 # from a suspended state 325 self.client_instance.HOOK_on_session_has_resumed_by_other(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name) 326 elif _last_status['connected'] and _last_status['virgin']: 327 # as a new session, do not report directly after connect due to many false positives then... 328 self.client_instance.HOOK_on_session_has_started_by_other(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name) 329 330 elif _last_status['connected'] and (not _last_status['suspended'] and _current_status['suspended']) and not _current_status['faulty'] and _session_name: 331 332 # unregister as master session 333 if _profile_name in self.master_sessions.keys(): 334 if self.master_sessions[_profile_name] == self(_session_uuid): 335 336 # save exported folders to session profile config if requested by session profile parameter ,,restoreexports''... 337 if self.client_instance and self(_session_uuid).restore_shared_local_folders: 338 self.client_instance.set_profile_config(_profile_name, 'export', self(_session_uuid)._restore_exported_folders) 339 340 self(_session_uuid).unset_master_session() 341 del self.master_sessions[_profile_name] 342 343 # session has been suspended 344 self(_session_uuid).session_cleanup() 345 self.client_instance.HOOK_on_session_has_been_suspended(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name) 346 347 elif _last_status['connected'] and (not _last_status['terminated'] and _current_status['terminated']) and not _current_status['faulty'] and _session_name: 348 349 # unregister as master session 350 if _profile_name in self.master_sessions.keys(): 351 if self.master_sessions[_profile_name] == self(_session_uuid): 352 353 # save exported folders to session profile config if requested by session profile parameter ,,restoreexports''... 354 if self.client_instance and self(_session_uuid).restore_shared_local_folders: 355 self.client_instance.set_profile_config(_profile_name, 'export', self(_session_uuid)._restore_exported_folders) 356 357 self(_session_uuid).unset_master_session() 358 del self.master_sessions[_profile_name] 359 360 # session has terminated 361 self.client_instance.HOOK_on_session_has_terminated(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name) 362 try: self(_session_uuid).session_cleanup() 363 except x2go_exceptions.X2goSessionException: pass 364 try: self(_session_uuid).__del__() 365 except x2go_exceptions.X2goSessionException: pass 366 if len(self.virgin_sessions_of_profile_name(profile_name)) > 1: 367 self.forget(_session_uuid) 368 369 # detect master sessions for connected profiles that have lost (suspend/terminate) their master session or never had a master session 370 for _profile_name in [ p for p in self.connected_profiles(return_profile_names=True) if p not in self.master_sessions.keys() ]: 371 _running_associated_sessions = [ _s for _s in self.running_sessions_of_profile_name(_profile_name, return_objects=True) if _s.is_associated() ] 372 if _running_associated_sessions: 373 for _r_a_s in _running_associated_sessions: 374 if _r_a_s.is_desktop_session(): 375 self.master_sessions[_profile_name] = _r_a_s 376 _r_a_s.set_master_session(wait=1) 377 break 378 if not self.master_sessions.has_key(_profile_name): 379 _pubapp_associated_sessions = self.pubapp_sessions_of_profile_name(_profile_name, return_objects=True) 380 if _pubapp_associated_sessions: 381 self.master_sessions[_profile_name] = _pubapp_associated_sessions[0] 382 _pubapp_associated_sessions[0].set_master_session(wait=2) 383 else: 384 self.master_sessions[_profile_name] = _running_associated_sessions[0] 385 _running_associated_sessions[0].set_master_session(wait=2) 386 387 return True
388
389 - def register_available_server_sessions(self, profile_name, session_list=None, newly_connected=False, re_register=False, skip_pubapp_sessions=False):
390 """\ 391 Register server-side available X2Go sessions with this L{X2goSessionRegistry} instance for a given profile name. 392 393 @param profile_name: session profile name to register available X2Go sessions for 394 @type profile_name: C{str} 395 @param session_list: an optional C{X2goServerSessionList*} instance (as returned by the L{X2goClient.list_sessions()} command can 396 be passed to this method. 397 @type session_list: C{X2goServerSessionList*} instance 398 @param newly_connected: give a hint that the session profile got newly connected 399 @type newly_connected: C{bool} 400 @param re_register: re-register available sessions, needs to be done after changes to the session profile 401 @type re_register: C{bool} 402 @param skip_pubapp_sessions: Do not register published applications sessions 403 @type skip_pubapp_sessions: C{bool} 404 405 """ 406 if self._last_available_session_registration is not None: 407 _now = time.time() 408 _time_delta = _now - self._last_available_session_registration 409 if _time_delta < 2 and not re_register: 410 self.logger('registration interval too short (%s), skipping automatic session registration...' % _time_delta, loglevel=log.loglevel_DEBUG) 411 return 412 self._last_available_session_registration = _now 413 414 _connected_sessions = self.connected_sessions_of_profile_name(profile_name=profile_name, return_objects=False) 415 _registered_sessions = self.registered_sessions_of_profile_name(profile_name=profile_name, return_objects=False) 416 _session_names = [ self(s_uuid).session_name for s_uuid in _registered_sessions if self(s_uuid).session_name is not None ] 417 418 if _connected_sessions: 419 # any of the connected sessions is valuable for accessing the profile's control 420 # session commands, so we simply take the first that comes in... 421 _ctrl_session = self(_connected_sessions[0]) 422 423 if session_list is None: 424 session_list = _ctrl_session.list_sessions() 425 426 # make sure the session registry gets updated before registering new session 427 # (if the server name has changed, this will kick out obsolete X2goSessions) 428 self.update_status(profile_name=profile_name, session_list=session_list, force_update=True) 429 for session_name in session_list.keys(): 430 if (session_name not in _session_names and not self._skip_auto_registration) or re_register: 431 server = _ctrl_session.get_server_hostname() 432 profile_id = _ctrl_session.get_profile_id() 433 434 # reconstruct all session options of _ctrl_session to auto-register a suspended session 435 # found on the _ctrl_session's connected server 436 _clone_kwargs = _ctrl_session.__dict__ 437 kwargs = {} 438 kwargs.update(self.client_instance.session_profiles.to_session_params(profile_id)) 439 kwargs['client_instance'] = self.client_instance 440 kwargs['control_backend'] = _clone_kwargs['control_backend'] 441 kwargs['terminal_backend'] = _clone_kwargs['terminal_backend'] 442 kwargs['proxy_backend'] = _clone_kwargs['proxy_backend'] 443 kwargs['info_backend'] = _clone_kwargs['info_backend'] 444 kwargs['list_backend'] = _clone_kwargs['list_backend'] 445 kwargs['settings_backend'] = _clone_kwargs['settings_backend'] 446 kwargs['printing_backend'] = _clone_kwargs['printing_backend'] 447 kwargs['keep_controlsession_alive'] = _clone_kwargs['keep_controlsession_alive'] 448 kwargs['client_rootdir'] = _clone_kwargs['client_rootdir'] 449 kwargs['sessions_rootdir'] = _clone_kwargs['sessions_rootdir'] 450 451 try: del kwargs['server'] 452 except: pass 453 try: del kwargs['profile_name'] 454 except: pass 455 try: del kwargs['profile_id'] 456 except: pass 457 458 # this if clause catches problems when x2golistsessions commands give weird results 459 if not self.has_session_of_session_name(session_name) or re_register: 460 if not (skip_pubapp_sessions and re.match('.*_stRPUBLISHED_.*', session_name)): 461 session_uuid = self.register(server, profile_id, profile_name, 462 session_name=session_name, virgin=False, 463 **kwargs 464 ) 465 self(session_uuid).connected = True 466 self.update_status(session_uuid=session_uuid, force_update=True, newly_connected=newly_connected)
467
468 - def register(self, server, profile_id, profile_name, 469 session_name=None, 470 control_backend=_X2goControlSession, 471 terminal_backend=_X2goTerminalSession, 472 info_backend=_X2goServerSessionInfo, 473 list_backend=_X2goServerSessionList, 474 proxy_backend=_X2goProxy, 475 settings_backend=_X2goClientSettings, 476 printing_backend=_X2goClientPrinting, 477 client_rootdir=os.path.join(_LOCAL_HOME,_X2GO_CLIENT_ROOTDIR), 478 sessions_rootdir=os.path.join(_LOCAL_HOME,_X2GO_SESSIONS_ROOTDIR), 479 ssh_rootdir=os.path.join(_LOCAL_HOME,_X2GO_SSH_ROOTDIR), 480 keep_controlsession_alive=True, 481 add_to_known_hosts=False, 482 known_hosts=None, 483 **kwargs):
484 """\ 485 Register a new L{X2goSession} instance with this L{X2goSessionRegistry}. 486 487 @param server: hostname of X2Go server 488 @type server: C{str} 489 @param profile_id: profile ID 490 @type profile_id: C{str} 491 @param profile_name: profile name 492 @type profile_name: C{str} 493 @param session_name: session name (if available) 494 @type session_name: C{str} 495 @param control_backend: X2Go control session backend to use 496 @type control_backend: C{class} 497 @param terminal_backend: X2Go terminal session backend to use 498 @type terminal_backend: C{class} 499 @param info_backend: X2Go session info backend to use 500 @type info_backend: C{class} 501 @param list_backend: X2Go session list backend to use 502 @type list_backend: C{class} 503 @param proxy_backend: X2Go proxy backend to use 504 @type proxy_backend: C{class} 505 @param settings_backend: X2Go client settings backend to use 506 @type settings_backend: C{class} 507 @param printing_backend: X2Go client printing backend to use 508 @type printing_backend: C{class} 509 @param client_rootdir: client base dir (default: ~/.x2goclient) 510 @type client_rootdir: C{str} 511 @param sessions_rootdir: sessions base dir (default: ~/.x2go) 512 @type sessions_rootdir: C{str} 513 @param ssh_rootdir: ssh base dir (default: ~/.ssh) 514 @type ssh_rootdir: C{str} 515 @param keep_controlsession_alive: On last L{X2goSession.disconnect()} keep the associated C{X2goControlSession*} instance alive? 516 @ŧype keep_controlsession_alive: C{bool} 517 @param add_to_known_hosts: Auto-accept server host validity? 518 @type add_to_known_hosts: C{bool} 519 @param known_hosts: the underlying Paramiko/SSH systems C{known_hosts} file 520 @type known_hosts: C{str} 521 @param kwargs: all other options will be passed on to the constructor of the to-be-instantiated L{X2goSession} instance 522 @type C{dict} 523 524 @return: the session UUID of the newly registered (or re-registered) session 525 @rtype: C{str} 526 527 """ 528 if profile_id not in self._profile_locks.keys(): 529 self._profile_locks[profile_id] = threading.Lock() 530 531 self._profile_locks[profile_id].acquire() 532 533 control_session = None 534 if profile_id in self.control_sessions.keys(): 535 control_session = self.control_sessions[profile_id] 536 537 try: 538 _params = self.client_instance.session_profiles.to_session_params(profile_id) 539 540 except x2go_exceptions.X2goProfileException: 541 _params = utils._convert_SessionProfileOptions_2_SessionParams(_X2GO_SESSIONPROFILE_DEFAULTS) 542 543 for _k in _params.keys(): 544 if _k in kwargs.keys(): 545 _params[_k] = kwargs[_k] 546 547 # when starting a new session, we will try to use unused registered virgin sessions 548 # depending on your application layout, there should either be one or no such virgin session at all 549 _virgin_sessions = [ s for s in self.virgin_sessions_of_profile_name(profile_name, return_objects=True) if not s.activated ] 550 if _virgin_sessions and not session_name: 551 session_uuid = _virgin_sessions[0].get_uuid() 552 self(session_uuid).activated = True 553 self.logger('using already initially-registered yet-unused session %s' % session_uuid, loglevel=log.loglevel_NOTICE) 554 555 else: 556 session_uuid = self.get_session_of_session_name(session_name) 557 if session_uuid is not None: self.logger('using already registered-by-session-name session %s' % session_uuid, loglevel=log.loglevel_NOTICE) 558 559 if session_uuid is not None: 560 self(session_uuid).activated = True 561 self(session_uuid).update_params(_params) 562 self(session_uuid).set_server(server) 563 self(session_uuid).set_profile_name(profile_name) 564 self._profile_locks[profile_id].release() 565 return session_uuid 566 567 try: del _params['server'] 568 except: pass 569 try: del _params['profile_name'] 570 except: pass 571 try: del _params['profile_id'] 572 except: pass 573 574 s = session.X2goSession(server=server, control_session=control_session, 575 profile_id=profile_id, profile_name=profile_name, 576 session_name=session_name, 577 control_backend=control_backend, 578 terminal_backend=terminal_backend, 579 info_backend=info_backend, 580 list_backend=list_backend, 581 proxy_backend=proxy_backend, 582 settings_backend=settings_backend, 583 printing_backend=printing_backend, 584 client_rootdir=client_rootdir, 585 sessions_rootdir=sessions_rootdir, 586 ssh_rootdir=ssh_rootdir, 587 keep_controlsession_alive=keep_controlsession_alive, 588 add_to_known_hosts=add_to_known_hosts, 589 known_hosts=known_hosts, 590 client_instance=self.client_instance, 591 logger=self.logger, **_params) 592 593 session_uuid = s._X2goSession__get_uuid() 594 self.logger('registering X2Go session %s...' % profile_name, log.loglevel_NOTICE) 595 self.logger('registering X2Go session with UUID %s' % session_uuid, log.loglevel_DEBUG) 596 597 self.registry[session_uuid] = s 598 if profile_id not in self.control_sessions.keys(): 599 self.control_sessions[profile_id] = s.get_control_session() 600 601 # make sure a new session is a non-master session unless promoted in update_status method 602 self(session_uuid).unset_master_session() 603 if control_session is None: 604 self(session_uuid).do_auto_connect() 605 606 self._profile_locks[profile_id].release() 607 return session_uuid
608
609 - def has_session_of_session_name(self, session_name):
610 """\ 611 Detect if we know about an L{X2goSession} of name C{<session_name>}. 612 613 @param session_name: name of session to be searched for 614 @type session_name: C{str} 615 616 @return: C{True} if a session of C{<session_name>} has been found 617 @rtype: C{bool} 618 619 """ 620 return bool(self.get_session_of_session_name(session_name))
621
622 - def get_session_of_session_name(self, session_name, return_object=False):
623 """\ 624 Retrieve the L{X2goSession} instance with session name C{<session_name>}. 625 626 @param session_name: name of session to be retrieved 627 @type session_name: C{str} 628 @param return_object: if C{False} the session UUID hash will be returned, if C{True} the L{X2goSession} instance will be returned 629 @type return_object: C{bool} 630 631 @return: L{X2goSession} object or its representing session UUID hash 632 @rtype: L{X2goSession} instance or C{str} 633 634 @raise X2goSessionRegistryException: if there is more than one L{X2goSession} registered for C{<session_name>} within 635 the same L{X2goClient} instance. This should never happen! 636 637 """ 638 found_sessions = [ s for s in self.registered_sessions() if s.session_name == session_name and s.session_name is not None ] 639 if len(found_sessions) == 1: 640 session = found_sessions[0] 641 if return_object: 642 return session 643 else: 644 return session.get_uuid() 645 elif len(found_sessions) > 1: 646 raise x2go_exceptions.X2goSessionRegistryException('there should only be one registered session of name ,,%s\'\'' % session_name) 647 else: 648 return None
649
650 - def _sessionsWithState(self, state, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
651 if state == 'associated': 652 sessions = [ ts for ts in self.registry.values() if ts.has_terminal_session() ] 653 elif state == 'registered': 654 sessions = [ ts for ts in self.registry.values() ] 655 else: 656 sessions = [ ts for ts in self.registry.values() if eval('ts.%s' % state) ] 657 if return_profile_names: 658 profile_names = [] 659 for session in sessions: 660 if session.profile_name not in profile_names: 661 profile_names.append(session.profile_name) 662 return profile_names 663 elif return_profile_ids: 664 profile_ids = [] 665 for session in sessions: 666 if session.profile_id not in profile_ids: 667 profile_ids.append(session.profile_id) 668 return profile_ids 669 elif return_session_names: 670 session_names = [] 671 for session in sessions: 672 if session.session_name not in session_names: 673 session_names.append(session.session_name) 674 return session_names 675 elif return_objects: 676 return sessions 677 else: 678 return [s.get_uuid() for s in sessions ]
679
680 - def connected_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
681 """\ 682 Retrieve a list of sessions that the underlying L{X2goClient} instances is currently connected to. 683 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 684 685 @param return_objects: return as list of L{X2goSession} instances 686 @type return_objects: C{bool} 687 @param return_profile_names: return as list of profile names 688 @type return_profile_names: C{bool} 689 @param return_profile_ids: return as list of profile IDs 690 @type return_profile_ids: C{bool} 691 @param return_session_names: return as list of X2Go session names 692 @type return_session_names: C{bool} 693 694 @return: a session list (as UUID hashes, objects, profile names/IDs or session names) 695 @rtype: C{list} 696 697 """ 698 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)
699
700 - def associated_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
701 """\ 702 Retrieve a list of sessions that are currently associated by an C{X2goTerminalSession*} to the underlying L{X2goClient} instance. 703 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 704 705 @param return_objects: return as list of L{X2goSession} instances 706 @type return_objects: C{bool} 707 @param return_profile_names: return as list of profile names 708 @type return_profile_names: C{bool} 709 @param return_profile_ids: return as list of profile IDs 710 @type return_profile_ids: C{bool} 711 @param return_session_names: return as list of X2Go session names 712 @type return_session_names: C{bool} 713 714 @return: a session list (as UUID hashes, objects, profile names/IDs or session names) 715 @rtype: C{list} 716 717 """ 718 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)
719
720 - def virgin_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
721 """\ 722 Retrieve a list of sessions that are currently still in virgin state (not yet connected, associated etc.). 723 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 724 725 @param return_objects: return as list of L{X2goSession} instances 726 @type return_objects: C{bool} 727 @param return_profile_names: return as list of profile names 728 @type return_profile_names: C{bool} 729 @param return_profile_ids: return as list of profile IDs 730 @type return_profile_ids: C{bool} 731 @param return_session_names: return as list of X2Go session names 732 @type return_session_names: C{bool} 733 734 @return: a session list (as UUID hashes, objects, profile names/IDs or session names) 735 @rtype: C{list} 736 737 """ 738 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)
739
740 - def running_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
741 """\ 742 Retrieve a list of sessions that are currently in running state. 743 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 744 745 @param return_objects: return as list of L{X2goSession} instances 746 @type return_objects: C{bool} 747 @param return_profile_names: return as list of profile names 748 @type return_profile_names: C{bool} 749 @param return_profile_ids: return as list of profile IDs 750 @type return_profile_ids: C{bool} 751 @param return_session_names: return as list of X2Go session names 752 @type return_session_names: C{bool} 753 754 @return: a session list (as UUID hashes, objects, profile names/IDs or session names) 755 @rtype: C{list} 756 757 """ 758 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)
759
760 - def suspended_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
761 """\ 762 Retrieve a list of sessions that are currently in suspended state. 763 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 764 765 @param return_objects: return as list of L{X2goSession} instances 766 @type return_objects: C{bool} 767 @param return_profile_names: return as list of profile names 768 @type return_profile_names: C{bool} 769 @param return_profile_ids: return as list of profile IDs 770 @type return_profile_ids: C{bool} 771 @param return_session_names: return as list of X2Go session names 772 @type return_session_names: C{bool} 773 774 @return: a session list (as UUID hashes, objects, profile names/IDs or session names) 775 @rtype: C{list} 776 777 """ 778 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)
779
780 - def terminated_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
781 """\ 782 Retrieve a list of sessions that have terminated recently. 783 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 784 785 @param return_objects: return as list of L{X2goSession} instances 786 @type return_objects: C{bool} 787 @param return_profile_names: return as list of profile names 788 @type return_profile_names: C{bool} 789 @param return_profile_ids: return as list of profile IDs 790 @type return_profile_ids: C{bool} 791 @param return_session_names: return as list of X2Go session names 792 @type return_session_names: C{bool} 793 794 @return: a session list (as UUID hashes, objects, profile names/IDs or session names) 795 @rtype: C{list} 796 797 """ 798 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)
799 800 @property
801 - def has_running_sessions(self):
802 """\ 803 Equals C{True} if the underlying L{X2goClient} instance has any running sessions at hand. 804 805 """ 806 return self.running_sessions() and len(self.running_sessions()) > 0
807 808 @property
809 - def has_suspended_sessions(self):
810 """\ 811 Equals C{True} if the underlying L{X2goClient} instance has any suspended sessions at hand. 812 813 """ 814 return self.suspended_sessions and len(self.suspended_sessions) > 0
815
816 - def registered_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
817 """\ 818 Retrieve a list of all registered sessions. 819 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 820 821 @param return_objects: return as list of L{X2goSession} instances 822 @type return_objects: C{bool} 823 @param return_profile_names: return as list of profile names 824 @type return_profile_names: C{bool} 825 @param return_profile_ids: return as list of profile IDs 826 @type return_profile_ids: C{bool} 827 @param return_session_names: return as list of X2Go session names 828 @type return_session_names: C{bool} 829 830 @return: a session list (as UUID hashes, objects, profile names/IDs or session names) 831 @rtype: C{list} 832 833 """ 834 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)
835
836 - def non_running_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
837 """\ 838 Retrieve a list of sessions that are currently _NOT_ in running state. 839 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 840 841 @param return_objects: return as list of L{X2goSession} instances 842 @type return_objects: C{bool} 843 @param return_profile_names: return as list of profile names 844 @type return_profile_names: C{bool} 845 @param return_profile_ids: return as list of profile IDs 846 @type return_profile_ids: C{bool} 847 @param return_session_names: return as list of X2Go session names 848 @type return_session_names: C{bool} 849 850 @return: a session list (as UUID hashes, objects, profile names/IDs or session names) 851 @rtype: C{list} 852 853 """ 854 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) ]
855
856 - def connected_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
857 """\ 858 For a given session profile name retrieve a list of sessions that are currently connected to the profile's X2Go server. 859 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 860 861 @param profile_name: session profile name 862 @type profile_name: C{str} 863 @param return_objects: return as list of L{X2goSession} instances 864 @type return_objects: C{bool} 865 @param return_session_names: return as list of X2Go session names 866 @type return_session_names: C{bool} 867 868 @return: a session list (as UUID hashes, objects or session names) 869 @rtype: C{list} 870 871 """ 872 if return_objects: 873 return self.connected_sessions() and [ s for s in self.connected_sessions() if s.get_profile_name() == profile_name ] 874 elif return_session_names: 875 return self.connected_sessions() and [ s.session_name for s in self.connected_sessions() if s.get_profile_name() == profile_name ] 876 else: 877 return self.connected_sessions() and [ s.get_uuid() for s in self.connected_sessions() if s.get_profile_name() == profile_name ]
878
879 - def associated_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
880 """\ 881 For a given session profile name retrieve a list of sessions that are currently associated by an C{X2goTerminalSession*} to this L{X2goClient} instance. 882 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 883 884 @param profile_name: session profile name 885 @type profile_name: C{str} 886 @param return_objects: return as list of L{X2goSession} instances 887 @type return_objects: C{bool} 888 @param return_session_names: return as list of X2Go session names 889 @type return_session_names: C{bool} 890 891 @return: a session list (as UUID hashes, objects or session names) 892 @rtype: C{list} 893 894 """ 895 if return_objects: 896 return self.associated_sessions() and [ s for s in self.associated_sessions() if s.get_profile_name() == profile_name ] 897 elif return_session_names: 898 return self.associated_sessions() and [ s.session_name for s in self.associated_sessions() if s.get_profile_name() == profile_name ] 899 else: 900 return self.associated_sessions() and [ s.get_uuid() for s in self.associated_sessions() if s.get_profile_name() == profile_name ]
901
902 - def pubapp_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
903 """\ 904 For a given session profile name retrieve a list of sessions that can be providers for published application list. 905 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 906 907 @param profile_name: session profile name 908 @type profile_name: C{str} 909 @param return_objects: return as list of L{X2goSession} instances 910 @type return_objects: C{bool} 911 @param return_session_names: return as list of X2Go session names 912 @type return_session_names: C{bool} 913 914 @return: a session list (as UUID hashes, objects or session names) 915 @rtype: C{list} 916 917 """ 918 if return_objects: 919 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() ] 920 elif return_session_names: 921 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() ] 922 else: 923 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() ]
924
925 - def registered_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
926 """\ 927 For a given session profile name retrieve a list of sessions that are currently registered with this L{X2goClient} instance. 928 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 929 930 @param profile_name: session profile name 931 @type profile_name: C{str} 932 @param return_objects: return as list of L{X2goSession} instances 933 @type return_objects: C{bool} 934 @param return_session_names: return as list of X2Go session names 935 @type return_session_names: C{bool} 936 937 @return: a session list (as UUID hashes, objects or session names) 938 @rtype: C{list} 939 940 """ 941 942 if return_objects: 943 return self.registered_sessions() and [ s for s in self.registered_sessions() if s.get_profile_name() == profile_name ] 944 elif return_session_names: 945 return self.registered_sessions() and [ s.session_name for s in self.registered_sessions() if s.get_profile_name() == profile_name ] 946 else: 947 return self.registered_sessions() and [ s.get_uuid() for s in self.registered_sessions() if s.get_profile_name() == profile_name ]
948
949 - def virgin_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
950 """\ 951 For a given session profile name retrieve a list of sessions that are registered with this L{X2goClient} instance but have not 952 yet been started (i.e. sessions that are in virgin state). If none of the C{return_*} options is specified a list of 953 session UUID hashes will be returned. 954 955 @param profile_name: session profile name 956 @type profile_name: C{str} 957 @param return_objects: return as list of L{X2goSession} instances 958 @type return_objects: C{bool} 959 @param return_session_names: return as list of X2Go session names 960 @type return_session_names: C{bool} 961 962 @return: a session list (as UUID hashes, objects or session names) 963 @rtype: C{list} 964 965 """ 966 if return_objects: 967 return self.virgin_sessions() and [ s for s in self.virgin_sessions() if s.get_profile_name() == profile_name ] 968 elif return_session_names: 969 return self.virgin_sessions() and [ s.session_name for s in self.virgin_sessions() if s.get_profile_name() == profile_name ] 970 else: 971 return self.virgin_sessions() and [ s.get_uuid() for s in self.virgin_sessions() if s.get_profile_name() == profile_name ]
972
973 - def running_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
974 """\ 975 For a given session profile name retrieve a list of sessions that are currently running. 976 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 977 978 @param profile_name: session profile name 979 @type profile_name: C{str} 980 @param return_objects: return as list of L{X2goSession} instances 981 @type return_objects: C{bool} 982 @param return_session_names: return as list of X2Go session names 983 @type return_session_names: C{bool} 984 985 @return: a session list (as UUID hashes, objects or session names) 986 @rtype: C{list} 987 988 """ 989 if return_objects: 990 return self.running_sessions() and [ s for s in self.running_sessions() if s.get_profile_name() == profile_name ] 991 elif return_session_names: 992 return self.running_sessions() and [ s.session_name for s in self.running_sessions() if s.get_profile_name() == profile_name ] 993 else: 994 return self.running_sessions() and [ s.get_uuid() for s in self.running_sessions() if s.get_profile_name() == profile_name ]
995
996 - def suspended_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
997 """\ 998 For a given session profile name retrieve a list of sessions that are currently in suspended state. 999 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 1000 1001 @param profile_name: session profile name 1002 @type profile_name: C{str} 1003 @param return_objects: return as list of L{X2goSession} instances 1004 @type return_objects: C{bool} 1005 @param return_session_names: return as list of X2Go session names 1006 @type return_session_names: C{bool} 1007 1008 @return: a session list (as UUID hashes, objects or session names) 1009 @rtype: C{list} 1010 1011 """ 1012 if return_objects: 1013 return self.suspended_sessions() and [ s for s in self.suspended_sessions() if s.get_profile_name() == profile_name ] 1014 elif return_session_names: 1015 return self.suspended_sessions() and [ s.session_name for s in self.suspended_sessions() if s.get_profile_name() == profile_name ] 1016 else: 1017 return self.suspended_sessions() and [ s.get_uuid() for s in self.suspended_sessions() if s.get_profile_name() == profile_name ]
1018
1019 - def control_session_of_profile_name(self, profile_name):
1020 """\ 1021 For a given session profile name retrieve a the corresponding C{X2goControlSession*} instance. 1022 1023 @param profile_name: session profile name 1024 @type profile_name: C{str} 1025 1026 @return: contol session instance 1027 @rtype: C{X2goControlSession*} instance 1028 1029 """ 1030 _sessions = self.registered_sessions_of_profile_name(profile_name, return_objects=True) 1031 if _sessions: 1032 session = _sessions[0] 1033 return session.control_session 1034 return None
1035 1036 @property
1037 - def connected_control_sessions(self):
1038 """\ 1039 Equals a list of all currently connected control sessions. 1040 1041 """ 1042 return [ c for c in self.control_sessions.values() if c.is_connected() ]
1043
1044 - def connected_profiles(self, use_paramiko=False, return_profile_ids=True, return_profile_names=False):
1045 """\ 1046 Retrieve a list of all currently connected session profiles. 1047 1048 @param use_paramiko: send query directly to the Paramiko/SSH layer 1049 @type use_paramiko: C{bool} 1050 1051 @return: list of connected session profiles 1052 @rtype: C{list} 1053 1054 """ 1055 if use_paramiko: 1056 return [ p for p in self.control_sessions.keys() if self.control_sessions[p].is_connected() ] 1057 else: 1058 return self.connected_sessions(return_profile_ids=return_profile_ids, return_profile_names=return_profile_names)
1059
1060 - def get_master_session(self, profile_name, return_object=True, return_session_name=False):
1061 """\ 1062 Retrieve the master session of a specific profile. 1063 1064 @param profile_name: the profile name that we query the master session of 1065 @type profile_name: C{str} 1066 @param return_object: return L{X2goSession} instance 1067 @type return_object: C{bool} 1068 @param return_session_name: return X2Go session name 1069 @type return_session_name: C{bool} 1070 1071 @return: a session list (as UUID hashes, objects, profile names/IDs or session names) 1072 @rtype: C{list} 1073 1074 """ 1075 if profile_name not in self.connected_profiles(return_profile_names=True): 1076 return None 1077 1078 if profile_name not in self.master_sessions.keys() or self.master_sessions[profile_name] is None: 1079 return None 1080 1081 _session = self.master_sessions[profile_name] 1082 1083 if not _session.is_master_session(): 1084 del self.master_sessions[profile_name] 1085 return None 1086 1087 if return_object: 1088 return _session 1089 elif return_session_name: 1090 return _session.get_session_name() 1091 else: 1092 return _session.get_uuid()
1093