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

Source Code for Module x2go.registry

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