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