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  # 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 self(_session_uuid).is_locked(): 275 continue 276 277 if not self(_session_uuid).update_status(session_list=session_list, force_update=force_update): 278 # skip this run, as nothing has changed since the last time... 279 continue 280 281 _last_status = copy.deepcopy(self(_session_uuid)._last_status) 282 _current_status = copy.deepcopy(self(_session_uuid)._current_status) 283 284 # at this point we hook into the X2GoClient instance and call notification methods 285 # that can be used to inform an application that something has happened 286 287 _profile_name = self(_session_uuid).get_profile_name() 288 _session_name = self(_session_uuid).get_session_name() 289 290 if self(_session_uuid).get_server_hostname() != _current_status['server']: 291 292 # if the server (hostname) has changed due to a configuration change we skip all notifications 293 self(_session_uuid).session_cleanup() 294 self(_session_uuid).__del__() 295 if len(self.virgin_sessions_of_profile_name(profile_name)) > 1: 296 del self.registry[_session_uuid] 297 298 elif not _last_status['running'] and _current_status['running'] and not _current_status['faulty']: 299 # session has started 300 if newly_connected: 301 # from a suspended state 302 self.client_instance.HOOK_on_found_session_running_after_connect(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name) 303 else: 304 # explicitly ask for the terminal_session object directly here, so we also get 'PENDING' terminal sessions here... 305 if self(_session_uuid).terminal_session: 306 307 # declare as master session if appropriate 308 if _profile_name not in self.master_sessions.keys(): 309 self.master_sessions[_profile_name] = self(_session_uuid) 310 self(_session_uuid).set_master_session() 311 312 elif (not self.master_sessions[_profile_name].is_desktop_session() and self(_session_uuid).is_desktop_session()) or \ 313 (not self.master_sessions[_profile_name].is_desktop_session() and self(_session_uuid).is_published_applications_provider()): 314 self(self.master_sessions[_profile_name]()).unset_master_session() 315 self.master_sessions[_profile_name] = self(_session_uuid) 316 self(_session_uuid).set_master_session() 317 318 if _last_status['suspended']: 319 # from a suspended state 320 self.client_instance.HOOK_on_session_has_resumed_by_me(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name) 321 elif _last_status['virgin']: 322 # as a new session 323 self.client_instance.HOOK_on_session_has_started_by_me(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name) 324 325 else: 326 if _last_status['suspended']: 327 # from a suspended state 328 self.client_instance.HOOK_on_session_has_resumed_by_other(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name) 329 elif _last_status['connected'] and _last_status['virgin']: 330 # as a new session, do not report directly after connect due to many false positives then... 331 self.client_instance.HOOK_on_session_has_started_by_other(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name) 332 333 elif _last_status['connected'] and (not _last_status['suspended'] and _current_status['suspended']) and not _current_status['faulty'] and _session_name: 334 335 # unregister as master session 336 if _profile_name in self.master_sessions.keys(): 337 if self.master_sessions[_profile_name] == self(_session_uuid): 338 339 self(_session_uuid).unset_master_session() 340 del self.master_sessions[_profile_name] 341 342 # session has been suspended 343 self(_session_uuid).session_cleanup() 344 self.client_instance.HOOK_on_session_has_been_suspended(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name) 345 346 elif _last_status['connected'] and (not _last_status['terminated'] and _current_status['terminated']) and not _current_status['faulty'] and _session_name: 347 348 # unregister as master session 349 if _profile_name in self.master_sessions.keys(): 350 if self.master_sessions[_profile_name] == self(_session_uuid): 351 352 self(_session_uuid).unset_master_session() 353 del self.master_sessions[_profile_name] 354 355 # session has terminated 356 self.client_instance.HOOK_on_session_has_terminated(session_uuid=_session_uuid, profile_name=_profile_name, session_name=_session_name) 357 try: self(_session_uuid).session_cleanup() 358 except x2go_exceptions.X2GoSessionException: pass 359 try: self(_session_uuid).__del__() 360 except x2go_exceptions.X2GoSessionException: pass 361 if len(self.virgin_sessions_of_profile_name(profile_name)) > 1: 362 self.forget(_session_uuid) 363 364 # detect master sessions for connected profiles that have lost (suspend/terminate) their master session or never had a master session 365 for _profile_name in [ p for p in self.connected_profiles(return_profile_names=True) if p not in self.master_sessions.keys() ]: 366 _running_associated_sessions = [ _s for _s in self.running_sessions_of_profile_name(_profile_name, return_objects=True) if _s.is_associated() ] 367 if _running_associated_sessions: 368 for _r_a_s in _running_associated_sessions: 369 if _r_a_s.is_desktop_session(): 370 self.master_sessions[_profile_name] = _r_a_s 371 _r_a_s.set_master_session(wait=1) 372 break 373 if not self.master_sessions.has_key(_profile_name): 374 _pubapp_associated_sessions = self.pubapp_sessions_of_profile_name(_profile_name, return_objects=True) 375 if _pubapp_associated_sessions: 376 self.master_sessions[_profile_name] = _pubapp_associated_sessions[0] 377 _pubapp_associated_sessions[0].set_master_session(wait=2) 378 else: 379 self.master_sessions[_profile_name] = _running_associated_sessions[0] 380 _running_associated_sessions[0].set_master_session(wait=2) 381 382 return True
383
384 - def register_available_server_sessions(self, profile_name, session_list=None, newly_connected=False, re_register=False, skip_pubapp_sessions=False):
385 """\ 386 Register server-side available X2Go sessions with this L{X2GoSessionRegistry} instance for a given profile name. 387 388 @param profile_name: session profile name to register available X2Go sessions for 389 @type profile_name: C{str} 390 @param session_list: an optional C{X2GoServerSessionList*} instance (as returned by the L{X2GoClient.list_sessions()} command can 391 be passed to this method. 392 @type session_list: C{X2GoServerSessionList*} instance 393 @param newly_connected: give a hint that the session profile got newly connected 394 @type newly_connected: C{bool} 395 @param re_register: re-register available sessions, needs to be done after changes to the session profile 396 @type re_register: C{bool} 397 @param skip_pubapp_sessions: Do not register published applications sessions 398 @type skip_pubapp_sessions: C{bool} 399 400 """ 401 if self._last_available_session_registration is not None: 402 _now = time.time() 403 _time_delta = _now - self._last_available_session_registration 404 if _time_delta < 2 and not re_register: 405 self.logger('registration interval too short (%s), skipping automatic session registration...' % _time_delta, loglevel=log.loglevel_DEBUG) 406 return 407 self._last_available_session_registration = _now 408 409 _connected_sessions = self.connected_sessions_of_profile_name(profile_name=profile_name, return_objects=False) 410 _registered_sessions = self.registered_sessions_of_profile_name(profile_name=profile_name, return_objects=False) 411 _session_names = [ self(s_uuid).session_name for s_uuid in _registered_sessions if self(s_uuid).session_name is not None ] 412 413 if _connected_sessions: 414 # any of the connected sessions is valuable for accessing the profile's control 415 # session commands, so we simply take the first that comes in... 416 _ctrl_session = self(_connected_sessions[0]) 417 418 if session_list is None: 419 session_list = _ctrl_session.list_sessions() 420 421 # make sure the session registry gets updated before registering new session 422 # (if the server name has changed, this will kick out obsolete X2GoSessions) 423 self.update_status(profile_name=profile_name, session_list=session_list, force_update=True) 424 for session_name in session_list.keys(): 425 if (session_name not in _session_names and not self._skip_auto_registration) or re_register: 426 server = _ctrl_session.get_server_hostname() 427 profile_id = _ctrl_session.get_profile_id() 428 429 # reconstruct all session options of _ctrl_session to auto-register a suspended session 430 # found on the _ctrl_session's connected server 431 _clone_kwargs = _ctrl_session.__dict__ 432 kwargs = {} 433 kwargs.update(self.client_instance.session_profiles.to_session_params(profile_id)) 434 kwargs['client_instance'] = self.client_instance 435 kwargs['control_backend'] = _clone_kwargs['control_backend'] 436 kwargs['terminal_backend'] = _clone_kwargs['terminal_backend'] 437 kwargs['proxy_backend'] = _clone_kwargs['proxy_backend'] 438 kwargs['info_backend'] = _clone_kwargs['info_backend'] 439 kwargs['list_backend'] = _clone_kwargs['list_backend'] 440 kwargs['settings_backend'] = _clone_kwargs['settings_backend'] 441 kwargs['printing_backend'] = _clone_kwargs['printing_backend'] 442 kwargs['keep_controlsession_alive'] = _clone_kwargs['keep_controlsession_alive'] 443 kwargs['client_rootdir'] = _clone_kwargs['client_rootdir'] 444 kwargs['sessions_rootdir'] = _clone_kwargs['sessions_rootdir'] 445 446 try: del kwargs['server'] 447 except: pass 448 try: del kwargs['profile_name'] 449 except: pass 450 try: del kwargs['profile_id'] 451 except: pass 452 453 # this if clause catches problems when x2golistsessions commands give weird results 454 if not self.has_session_of_session_name(session_name) or re_register: 455 if not (skip_pubapp_sessions and re.match('.*_stRPUBLISHED_.*', session_name)): 456 session_uuid = self.register(server, profile_id, profile_name, 457 session_name=session_name, virgin=False, 458 **kwargs 459 ) 460 self(session_uuid).connected = True 461 self.update_status(session_uuid=session_uuid, force_update=True, newly_connected=newly_connected)
462
463 - def register(self, server, profile_id, profile_name, 464 session_name=None, 465 control_backend=_X2GoControlSession, 466 terminal_backend=_X2GoTerminalSession, 467 info_backend=_X2GoServerSessionInfo, 468 list_backend=_X2GoServerSessionList, 469 proxy_backend=_X2GoProxy, 470 settings_backend=_X2GoClientSettings, 471 printing_backend=_X2GoClientPrinting, 472 client_rootdir=os.path.join(_LOCAL_HOME,_X2GO_CLIENT_ROOTDIR), 473 sessions_rootdir=os.path.join(_LOCAL_HOME,_X2GO_SESSIONS_ROOTDIR), 474 ssh_rootdir=os.path.join(_LOCAL_HOME,_X2GO_SSH_ROOTDIR), 475 keep_controlsession_alive=True, 476 add_to_known_hosts=False, 477 known_hosts=None, 478 **kwargs):
479 """\ 480 Register a new L{X2GoSession} instance with this L{X2GoSessionRegistry}. 481 482 @param server: hostname of X2Go server 483 @type server: C{str} 484 @param profile_id: profile ID 485 @type profile_id: C{str} 486 @param profile_name: profile name 487 @type profile_name: C{str} 488 @param session_name: session name (if available) 489 @type session_name: C{str} 490 @param control_backend: X2Go control session backend to use 491 @type control_backend: C{class} 492 @param terminal_backend: X2Go terminal session backend to use 493 @type terminal_backend: C{class} 494 @param info_backend: X2Go session info backend to use 495 @type info_backend: C{class} 496 @param list_backend: X2Go session list backend to use 497 @type list_backend: C{class} 498 @param proxy_backend: X2Go proxy backend to use 499 @type proxy_backend: C{class} 500 @param settings_backend: X2Go client settings backend to use 501 @type settings_backend: C{class} 502 @param printing_backend: X2Go client printing backend to use 503 @type printing_backend: C{class} 504 @param client_rootdir: client base dir (default: ~/.x2goclient) 505 @type client_rootdir: C{str} 506 @param sessions_rootdir: sessions base dir (default: ~/.x2go) 507 @type sessions_rootdir: C{str} 508 @param ssh_rootdir: ssh base dir (default: ~/.ssh) 509 @type ssh_rootdir: C{str} 510 @param keep_controlsession_alive: On last L{X2GoSession.disconnect()} keep the associated C{X2GoControlSession*} instance alive? 511 @ŧype keep_controlsession_alive: C{bool} 512 @param add_to_known_hosts: Auto-accept server host validity? 513 @type add_to_known_hosts: C{bool} 514 @param known_hosts: the underlying Paramiko/SSH systems C{known_hosts} file 515 @type known_hosts: C{str} 516 @param kwargs: all other options will be passed on to the constructor of the to-be-instantiated L{X2GoSession} instance 517 @type C{dict} 518 519 @return: the session UUID of the newly registered (or re-registered) session 520 @rtype: C{str} 521 522 """ 523 if profile_id not in self._profile_locks.keys(): 524 self._profile_locks[profile_id] = threading.Lock() 525 526 self._profile_locks[profile_id].acquire() 527 528 control_session = None 529 if profile_id in self.control_sessions.keys(): 530 control_session = self.control_sessions[profile_id] 531 532 try: 533 _params = self.client_instance.session_profiles.to_session_params(profile_id) 534 535 except x2go_exceptions.X2GoProfileException: 536 _params = utils._convert_SessionProfileOptions_2_SessionParams(_X2GO_SESSIONPROFILE_DEFAULTS) 537 538 for _k in _params.keys(): 539 if _k in kwargs.keys(): 540 _params[_k] = kwargs[_k] 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 session in sessions: 663 if session.profile_name not in profile_names: 664 profile_names.append(session.profile_name) 665 return profile_names 666 elif return_profile_ids: 667 profile_ids = [] 668 for session in sessions: 669 if session.profile_id not in profile_ids: 670 profile_ids.append(session.profile_id) 671 return profile_ids 672 elif return_session_names: 673 session_names = [] 674 for session in sessions: 675 if session.session_name not in session_names: 676 session_names.append(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