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

Source Code for Module x2go.registry

   1  # -*- coding: utf-8 -*- 
   2   
   3  # Copyright (C) 2010-2013 by Mike Gabriel <mike.gabriel@das-netzwerkteam.de> 
   4  # 
   5  # Python X2Go is free software; you can redistribute it and/or modify 
   6  # it under the terms of the GNU Affero General Public License as published by 
   7  # the Free Software Foundation; either version 3 of the License, or 
   8  # (at your option) any later version. 
   9  # 
  10  # Python X2Go is distributed in the hope that it will be useful, 
  11  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
  12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  13  # GNU Affero General Public License for more details. 
  14  # 
  15  # You should have received a copy of the GNU Affero General Public License 
  16  # along with this program; if not, write to the 
  17  # Free Software Foundation, Inc., 
  18  # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 
  19   
  20  """\ 
  21  X2GoSessionRegistry class - the X2GoClient's session registry backend 
  22   
  23  """ 
  24  __NAME__ = 'x2gosessregistry-pylib' 
  25   
  26  import os 
  27  import copy 
  28  import types 
  29  import time 
  30  import threading 
  31  import re 
  32   
  33  # Python X2Go modules 
  34  import log 
  35  import utils 
  36  import session 
  37  import x2go_exceptions 
  38   
  39  # import the default terminal session backend 
  40  from x2go.backends.control import X2GoControlSession as _X2GoControlSession 
  41  from x2go.backends.terminal import X2GoTerminalSession as _X2GoTerminalSession 
  42  from x2go.backends.info import X2GoServerSessionInfo as _X2GoServerSessionInfo 
  43  from x2go.backends.info import X2GoServerSessionList as _X2GoServerSessionList 
  44  from x2go.backends.proxy import X2GoProxy as _X2GoProxy 
  45  from x2go.backends.settings import X2GoClientSettings as _X2GoClientSettings 
  46  from x2go.backends.printing import X2GoClientPrinting as _X2GoClientPrinting 
  47   
  48  from defaults import LOCAL_HOME as _LOCAL_HOME 
  49  from defaults import X2GO_CLIENT_ROOTDIR as _X2GO_CLIENT_ROOTDIR 
  50  from defaults import X2GO_SESSIONS_ROOTDIR as _X2GO_SESSIONS_ROOTDIR 
  51  from defaults import X2GO_SESSIONPROFILE_DEFAULTS as _X2GO_SESSIONPROFILE_DEFAULTS 
  52  from defaults import X2GO_SSH_ROOTDIR as _X2GO_SSH_ROOTDIR 
53 54 -class X2GoSessionRegistry(object):
55 """\ 56 This class is utilized by L{X2GoClient} instances to maintain a good overview on 57 session status of all associated L{X2GoSession} instances. 58 59 """
60 - def __init__(self, client_instance, 61 logger=None, loglevel=log.loglevel_DEFAULT):
62 """\ 63 @param client_instance: the L{X2GoClient} instance that instantiated this L{X2GoSessionRegistry} instance. 64 @type client_instance: L{X2GoClient} instance 65 @param logger: you can pass an L{X2GoLogger} object to the L{X2GoClientXConfig} constructor 66 @type logger: C{obj} 67 @param loglevel: if no L{X2GoLogger} object has been supplied a new one will be 68 constructed with the given loglevel 69 @type loglevel: C{int} 70 71 """ 72 if logger is None: 73 self.logger = log.X2GoLogger(loglevel=loglevel) 74 else: 75 self.logger = copy.deepcopy(logger) 76 self.logger.tag = __NAME__ 77 78 self.client_instance = client_instance 79 80 self.registry = {} 81 self.control_sessions = {} 82 self.master_sessions = {} 83 84 self._last_available_session_registration = None 85 self._skip_auto_registration = False 86 self._profile_locks = {}
87
88 - def keys(self):
89 """\ 90 A list of session registry keys. 91 92 @return: session registry key list 93 @rtype: C{list} 94 95 """ 96 return self.registry.keys()
97
98 - def __repr__(self):
99 result = 'X2GoSessionRegistry(' 100 for p in dir(self): 101 if '__' in p or not p in self.__dict__ or type(p) is types.InstanceType: continue 102 result += p + '=' + str(self.__dict__[p]) + ',' 103 result = result.strip(',') 104 return result + ')'
105
106 - def __call__(self, session_uuid):
107 """\ 108 Returns the L{X2GoSession} instance for a given session UUID hash. 109 110 @param session_uuid: the X2Go session's UUID registry hash 111 @type session_uuid: C{str} 112 113 @return: the corresponding L{X2GoSession} instance 114 @rtype: L{X2GoSession} instance 115 116 @raise X2GoSessionRegistryException: if the given session UUID could not be found 117 118 """ 119 try: 120 return self.registry[session_uuid] 121 except KeyError: 122 raise x2go_exceptions.X2GoSessionRegistryException('No session found for UUID %s' % session_uuid)
123
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, match_profile_name=profile_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, match_profile_name=None):
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 @param match_profile_name: a session's profile_name must match this profile name 616 @type match_profile_name: C{str} 617 618 @return: C{True} if a session of C{<session_name>} has been found 619 @rtype: C{bool} 620 621 """ 622 return bool(self.get_session_of_session_name(session_name, match_profile_name=match_profile_name))
623
624 - def get_session_of_session_name(self, session_name, return_object=False, match_profile_name=None):
625 """\ 626 Retrieve the L{X2GoSession} instance with session name C{<session_name>}. 627 628 @param session_name: name of session to be retrieved 629 @type session_name: C{str} 630 @param return_object: if C{False} the session UUID hash will be returned, if C{True} the L{X2GoSession} instance will be returned 631 @type return_object: C{bool} 632 @param match_profile_name: returned sessions must match this profile name 633 @type match_profile_name: C{str} 634 635 @return: L{X2GoSession} object or its representing session UUID hash 636 @rtype: L{X2GoSession} instance or C{str} 637 638 @raise X2GoSessionRegistryException: if there is more than one L{X2GoSession} registered for C{<session_name>} within 639 the same L{X2GoClient} instance. This should never happen! 640 641 """ 642 if match_profile_name is None: 643 reg_sessions = self.registered_sessions() 644 else: 645 reg_sessions = self.registered_sessions_of_profile_name(match_profile_name) 646 found_sessions = [ s for s in reg_sessions if s.session_name == session_name and s.session_name is not None ] 647 if len(found_sessions) == 1: 648 session = found_sessions[0] 649 if return_object: 650 return session 651 else: 652 return session.get_uuid() 653 elif len(found_sessions) > 1: 654 raise x2go_exceptions.X2GoSessionRegistryException('there should only be one registered session of name ,,%s\'\'' % session_name) 655 else: 656 return None
657
658 - def _sessionsWithState(self, state, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
659 if state == 'associated': 660 sessions = [ ts for ts in self.registry.values() if ts.has_terminal_session() ] 661 elif state == 'registered': 662 sessions = [ ts for ts in self.registry.values() ] 663 else: 664 sessions = [ ts for ts in self.registry.values() if eval('ts.%s' % state) ] 665 if return_profile_names: 666 profile_names = [] 667 for session in sessions: 668 if session.profile_name not in profile_names: 669 profile_names.append(session.profile_name) 670 return profile_names 671 elif return_profile_ids: 672 profile_ids = [] 673 for session in sessions: 674 if session.profile_id not in profile_ids: 675 profile_ids.append(session.profile_id) 676 return profile_ids 677 elif return_session_names: 678 session_names = [] 679 for session in sessions: 680 if session.session_name not in session_names: 681 session_names.append(session.session_name) 682 return session_names 683 elif return_objects: 684 return sessions 685 else: 686 return [s.get_uuid() for s in sessions ]
687
688 - def connected_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
689 """\ 690 Retrieve a list of sessions that the underlying L{X2GoClient} instances is currently connected to. 691 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 692 693 @param return_objects: return as list of L{X2GoSession} instances 694 @type return_objects: C{bool} 695 @param return_profile_names: return as list of profile names 696 @type return_profile_names: C{bool} 697 @param return_profile_ids: return as list of profile IDs 698 @type return_profile_ids: C{bool} 699 @param return_session_names: return as list of X2Go session names 700 @type return_session_names: C{bool} 701 702 @return: a session list (as UUID hashes, objects, profile names/IDs or session names) 703 @rtype: C{list} 704 705 """ 706 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)
707
708 - def associated_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
709 """\ 710 Retrieve a list of sessions that are currently associated by an C{X2GoTerminalSession*} to the underlying L{X2GoClient} instance. 711 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 712 713 @param return_objects: return as list of L{X2GoSession} instances 714 @type return_objects: C{bool} 715 @param return_profile_names: return as list of profile names 716 @type return_profile_names: C{bool} 717 @param return_profile_ids: return as list of profile IDs 718 @type return_profile_ids: C{bool} 719 @param return_session_names: return as list of X2Go session names 720 @type return_session_names: C{bool} 721 722 @return: a session list (as UUID hashes, objects, profile names/IDs or session names) 723 @rtype: C{list} 724 725 """ 726 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)
727
728 - def virgin_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
729 """\ 730 Retrieve a list of sessions that are currently still in virgin state (not yet connected, associated etc.). 731 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 732 733 @param return_objects: return as list of L{X2GoSession} instances 734 @type return_objects: C{bool} 735 @param return_profile_names: return as list of profile names 736 @type return_profile_names: C{bool} 737 @param return_profile_ids: return as list of profile IDs 738 @type return_profile_ids: C{bool} 739 @param return_session_names: return as list of X2Go session names 740 @type return_session_names: C{bool} 741 742 @return: a session list (as UUID hashes, objects, profile names/IDs or session names) 743 @rtype: C{list} 744 745 """ 746 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)
747
748 - def running_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
749 """\ 750 Retrieve a list of sessions that are currently in running state. 751 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 752 753 @param return_objects: return as list of L{X2GoSession} instances 754 @type return_objects: C{bool} 755 @param return_profile_names: return as list of profile names 756 @type return_profile_names: C{bool} 757 @param return_profile_ids: return as list of profile IDs 758 @type return_profile_ids: C{bool} 759 @param return_session_names: return as list of X2Go session names 760 @type return_session_names: C{bool} 761 762 @return: a session list (as UUID hashes, objects, profile names/IDs or session names) 763 @rtype: C{list} 764 765 """ 766 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)
767
768 - def suspended_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
769 """\ 770 Retrieve a list of sessions that are currently in suspended state. 771 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 772 773 @param return_objects: return as list of L{X2GoSession} instances 774 @type return_objects: C{bool} 775 @param return_profile_names: return as list of profile names 776 @type return_profile_names: C{bool} 777 @param return_profile_ids: return as list of profile IDs 778 @type return_profile_ids: C{bool} 779 @param return_session_names: return as list of X2Go session names 780 @type return_session_names: C{bool} 781 782 @return: a session list (as UUID hashes, objects, profile names/IDs or session names) 783 @rtype: C{list} 784 785 """ 786 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)
787
788 - def terminated_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
789 """\ 790 Retrieve a list of sessions that have terminated recently. 791 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 792 793 @param return_objects: return as list of L{X2GoSession} instances 794 @type return_objects: C{bool} 795 @param return_profile_names: return as list of profile names 796 @type return_profile_names: C{bool} 797 @param return_profile_ids: return as list of profile IDs 798 @type return_profile_ids: C{bool} 799 @param return_session_names: return as list of X2Go session names 800 @type return_session_names: C{bool} 801 802 @return: a session list (as UUID hashes, objects, profile names/IDs or session names) 803 @rtype: C{list} 804 805 """ 806 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)
807 808 @property
809 - def has_running_sessions(self):
810 """\ 811 Equals C{True} if the underlying L{X2GoClient} instance has any running sessions at hand. 812 813 """ 814 return self.running_sessions() and len(self.running_sessions()) > 0
815 816 @property
817 - def has_suspended_sessions(self):
818 """\ 819 Equals C{True} if the underlying L{X2GoClient} instance has any suspended sessions at hand. 820 821 """ 822 return self.suspended_sessions and len(self.suspended_sessions) > 0
823
824 - def registered_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
825 """\ 826 Retrieve a list of all registered sessions. 827 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 828 829 @param return_objects: return as list of L{X2GoSession} instances 830 @type return_objects: C{bool} 831 @param return_profile_names: return as list of profile names 832 @type return_profile_names: C{bool} 833 @param return_profile_ids: return as list of profile IDs 834 @type return_profile_ids: C{bool} 835 @param return_session_names: return as list of X2Go session names 836 @type return_session_names: C{bool} 837 838 @return: a session list (as UUID hashes, objects, profile names/IDs or session names) 839 @rtype: C{list} 840 841 """ 842 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)
843
844 - def non_running_sessions(self, return_objects=True, return_profile_names=False, return_profile_ids=False, return_session_names=False):
845 """\ 846 Retrieve a list of sessions that are currently _NOT_ in running state. 847 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 848 849 @param return_objects: return as list of L{X2GoSession} instances 850 @type return_objects: C{bool} 851 @param return_profile_names: return as list of profile names 852 @type return_profile_names: C{bool} 853 @param return_profile_ids: return as list of profile IDs 854 @type return_profile_ids: C{bool} 855 @param return_session_names: return as list of X2Go session names 856 @type return_session_names: C{bool} 857 858 @return: a session list (as UUID hashes, objects, profile names/IDs or session names) 859 @rtype: C{list} 860 861 """ 862 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) ]
863
864 - def connected_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
865 """\ 866 For a given session profile name retrieve a list of sessions that are currently connected to the profile's X2Go server. 867 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 868 869 @param profile_name: session profile name 870 @type profile_name: C{str} 871 @param return_objects: return as list of L{X2GoSession} instances 872 @type return_objects: C{bool} 873 @param return_session_names: return as list of X2Go session names 874 @type return_session_names: C{bool} 875 876 @return: a session list (as UUID hashes, objects or session names) 877 @rtype: C{list} 878 879 """ 880 if return_objects: 881 return self.connected_sessions() and [ s for s in self.connected_sessions() if s.get_profile_name() == profile_name ] 882 elif return_session_names: 883 return self.connected_sessions() and [ s.session_name for s in self.connected_sessions() if s.get_profile_name() == profile_name ] 884 else: 885 return self.connected_sessions() and [ s.get_uuid() for s in self.connected_sessions() if s.get_profile_name() == profile_name ]
886
887 - def associated_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
888 """\ 889 For a given session profile name retrieve a list of sessions that are currently associated by an C{X2GoTerminalSession*} to this L{X2GoClient} instance. 890 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 891 892 @param profile_name: session profile name 893 @type profile_name: C{str} 894 @param return_objects: return as list of L{X2GoSession} instances 895 @type return_objects: C{bool} 896 @param return_session_names: return as list of X2Go session names 897 @type return_session_names: C{bool} 898 899 @return: a session list (as UUID hashes, objects or session names) 900 @rtype: C{list} 901 902 """ 903 if return_objects: 904 return self.associated_sessions() and [ s for s in self.associated_sessions() if s.get_profile_name() == profile_name ] 905 elif return_session_names: 906 return self.associated_sessions() and [ s.session_name for s in self.associated_sessions() if s.get_profile_name() == profile_name ] 907 else: 908 return self.associated_sessions() and [ s.get_uuid() for s in self.associated_sessions() if s.get_profile_name() == profile_name ]
909
910 - def pubapp_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
911 """\ 912 For a given session profile name retrieve a list of sessions that can be providers for published application list. 913 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 914 915 @param profile_name: session profile name 916 @type profile_name: C{str} 917 @param return_objects: return as list of L{X2GoSession} instances 918 @type return_objects: C{bool} 919 @param return_session_names: return as list of X2Go session names 920 @type return_session_names: C{bool} 921 922 @return: a session list (as UUID hashes, objects or session names) 923 @rtype: C{list} 924 925 """ 926 if return_objects: 927 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() ] 928 elif return_session_names: 929 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() ] 930 else: 931 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() ]
932
933 - def registered_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
934 """\ 935 For a given session profile name retrieve a list of sessions that are currently registered with this L{X2GoClient} instance. 936 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 937 938 @param profile_name: session profile name 939 @type profile_name: C{str} 940 @param return_objects: return as list of L{X2GoSession} instances 941 @type return_objects: C{bool} 942 @param return_session_names: return as list of X2Go session names 943 @type return_session_names: C{bool} 944 945 @return: a session list (as UUID hashes, objects or session names) 946 @rtype: C{list} 947 948 """ 949 if return_objects: 950 return self.registered_sessions() and [ s for s in self.registered_sessions() if s.get_profile_name() == profile_name ] 951 elif return_session_names: 952 return self.registered_sessions() and [ s.session_name for s in self.registered_sessions() if s.get_profile_name() == profile_name ] 953 else: 954 return self.registered_sessions() and [ s.get_uuid() for s in self.registered_sessions() if s.get_profile_name() == profile_name ]
955
956 - def virgin_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
957 """\ 958 For a given session profile name retrieve a list of sessions that are registered with this L{X2GoClient} instance but have not 959 yet been started (i.e. sessions that are in virgin state). If none of the C{return_*} options is specified a list of 960 session UUID hashes will be returned. 961 962 @param profile_name: session profile name 963 @type profile_name: C{str} 964 @param return_objects: return as list of L{X2GoSession} instances 965 @type return_objects: C{bool} 966 @param return_session_names: return as list of X2Go session names 967 @type return_session_names: C{bool} 968 969 @return: a session list (as UUID hashes, objects or session names) 970 @rtype: C{list} 971 972 """ 973 if return_objects: 974 return self.virgin_sessions() and [ s for s in self.virgin_sessions() if s.get_profile_name() == profile_name ] 975 elif return_session_names: 976 return self.virgin_sessions() and [ s.session_name for s in self.virgin_sessions() if s.get_profile_name() == profile_name ] 977 else: 978 return self.virgin_sessions() and [ s.get_uuid() for s in self.virgin_sessions() if s.get_profile_name() == profile_name ]
979
980 - def running_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
981 """\ 982 For a given session profile name retrieve a list of sessions that are currently running. 983 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 984 985 @param profile_name: session profile name 986 @type profile_name: C{str} 987 @param return_objects: return as list of L{X2GoSession} instances 988 @type return_objects: C{bool} 989 @param return_session_names: return as list of X2Go session names 990 @type return_session_names: C{bool} 991 992 @return: a session list (as UUID hashes, objects or session names) 993 @rtype: C{list} 994 995 """ 996 if return_objects: 997 return self.running_sessions() and [ s for s in self.running_sessions() if s.get_profile_name() == profile_name ] 998 elif return_session_names: 999 return self.running_sessions() and [ s.session_name for s in self.running_sessions() if s.get_profile_name() == profile_name ] 1000 else: 1001 return self.running_sessions() and [ s.get_uuid() for s in self.running_sessions() if s.get_profile_name() == profile_name ]
1002
1003 - def suspended_sessions_of_profile_name(self, profile_name, return_objects=True, return_session_names=False):
1004 """\ 1005 For a given session profile name retrieve a list of sessions that are currently in suspended state. 1006 If none of the C{return_*} options is specified a list of session UUID hashes will be returned. 1007 1008 @param profile_name: session profile name 1009 @type profile_name: C{str} 1010 @param return_objects: return as list of L{X2GoSession} instances 1011 @type return_objects: C{bool} 1012 @param return_session_names: return as list of X2Go session names 1013 @type return_session_names: C{bool} 1014 1015 @return: a session list (as UUID hashes, objects or session names) 1016 @rtype: C{list} 1017 1018 """ 1019 if return_objects: 1020 return self.suspended_sessions() and [ s for s in self.suspended_sessions() if s.get_profile_name() == profile_name ] 1021 elif return_session_names: 1022 return self.suspended_sessions() and [ s.session_name for s in self.suspended_sessions() if s.get_profile_name() == profile_name ] 1023 else: 1024 return self.suspended_sessions() and [ s.get_uuid() for s in self.suspended_sessions() if s.get_profile_name() == profile_name ]
1025
1026 - def control_session_of_profile_name(self, profile_name):
1027 """\ 1028 For a given session profile name retrieve a the corresponding C{X2GoControlSession*} instance. 1029 1030 @param profile_name: session profile name 1031 @type profile_name: C{str} 1032 1033 @return: contol session instance 1034 @rtype: C{X2GoControlSession*} instance 1035 1036 """ 1037 _sessions = self.registered_sessions_of_profile_name(profile_name, return_objects=True) 1038 if _sessions: 1039 session = _sessions[0] 1040 return session.control_session 1041 return None
1042 1043 @property
1044 - def connected_control_sessions(self):
1045 """\ 1046 Equals a list of all currently connected control sessions. 1047 1048 """ 1049 return [ c for c in self.control_sessions.values() if c.is_connected() ]
1050
1051 - def connected_profiles(self, use_paramiko=False, return_profile_ids=True, return_profile_names=False):
1052 """\ 1053 Retrieve a list of all currently connected session profiles. 1054 1055 @param use_paramiko: send query directly to the Paramiko/SSH layer 1056 @type use_paramiko: C{bool} 1057 1058 @return: list of connected session profiles 1059 @rtype: C{list} 1060 1061 """ 1062 if use_paramiko: 1063 return [ p for p in self.control_sessions.keys() if self.control_sessions[p].is_connected() ] 1064 else: 1065 return self.connected_sessions(return_profile_ids=return_profile_ids, return_profile_names=return_profile_names)
1066
1067 - def get_master_session(self, profile_name, return_object=True, return_session_name=False):
1068 """\ 1069 Retrieve the master session of a specific profile. 1070 1071 @param profile_name: the profile name that we query the master session of 1072 @type profile_name: C{str} 1073 @param return_object: return L{X2GoSession} instance 1074 @type return_object: C{bool} 1075 @param return_session_name: return X2Go session name 1076 @type return_session_name: C{bool} 1077 1078 @return: a session list (as UUID hashes, objects, profile names/IDs or session names) 1079 @rtype: C{list} 1080 1081 """ 1082 if profile_name not in self.connected_profiles(return_profile_names=True): 1083 return None 1084 1085 if profile_name not in self.master_sessions.keys() or self.master_sessions[profile_name] is None: 1086 return None 1087 1088 _session = self.master_sessions[profile_name] 1089 1090 if not _session.is_master_session(): 1091 del self.master_sessions[profile_name] 1092 return None 1093 1094 if return_object: 1095 return _session 1096 elif return_session_name: 1097 return _session.get_session_name() 1098 else: 1099 return _session.get_uuid()
1100