Package x2go :: Package backends :: Package info :: Module plain

[frames] | no frames]

# Source Code for Module x2go.backends.info.plain

      1  # -*- coding: utf-8 -*-
      2
      3  # Copyright (C) 2010-2016 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  X2GoServerSessionList and X2GoServerSessionInfo classes - data handling for
     22  X2Go server sessions.
     23
     24  This backend handles X2Go server implementations that respond with session infos
     25  via server-side PLAIN text output.
     26
     27  """
     28  __NAME__ = 'x2goserversessioninfo-pylib'
     29
     30
     31  # modules
     32  import types
     33  import re
     34
     35 -class X2GoServerSessionInfo(object):
     36      """\
     37      L{X2GoServerSessionInfo} is used to store all information
     38      that is retrieved from the connected X2Go server on
     39      C{X2GoTerminalSession.start()} resp. C{X2GoTerminalSession.resume()}.
     40
     41      """
     42 -    def __str__(self):
     43          return self.name
     44 -    def __repr__(self):
     45          result = 'X2GoServerSessionInfo('
     46          for p in dir(self):
     47              if '__' in p or not p in self.__dict__ or type(p) is types.InstanceType: continue
     48              result += p + '=' + str(self.__dict__[p]) +','
     49          return result.strip(',') + ')'
     50
     51 -    def _parse_x2golistsessions_line(self, x2go_output):
     52          """\
     53          Parse a single line of X2Go's listsessions output.
     54
     55          @param x2go_output: output from ,,x2golistsessions'' command (as list of strings/lines)
     56          @type x2go_output: C{list}
     57
     58          """
     59          try:
     60              l = x2go_output.split("|")
     61              self.agent_pid = int(l[0])
     62              self.name = l[1]
     63              self.display = int(l[2])
     64              self.hostname = l[3]
     65              self.status = l[4]
     66              # TODO: turn into datetime object
     67              self.date_created = l[5]
     68              self.cookie = l[6]
     69              self.graphics_port = int(l[8])
     70              self.snd_port = int(l[9])
     71              # TODO: turn into datetime object
     72              self.date_suspended = l[10]
     73              self.username = l[11]
     74              self.sshfs_port = int(l[13])
     75              self.local_container = ''
     76          except IndexError, e:
     77              # DEBUGGING CODE
     78              raise e
     79          except ValueError, e:
     80              # DEBUGGING CODE
     81              raise e
     82
     83          # retrieve Telekinesis ports from list of sessions...
     84          try:
     85              self.tekictrl_port = int(l[14])
     86          except (IndexError, ValueError), e:
     87              self.tekictrl_port = -1
     88          try:
     89              self.tekidata_port = int(l[15])
     90          except (IndexError, ValueError), e:
     91              self.tekidata_port = -1
     92
     93 -    def is_published_applications_provider(self):
     94          """\
     95          Detect from session info if this session is a published applications provider.
     96
     97          @return: returns C{True} if this session is a published applications provider
     98          @rtype: C{bool}
     99
    100          """
    101          return bool(re.match('.*_stRPUBLISHED_.*', self.name))
    102
    103 -    def is_running(self):
    104          """\
    105          Is this session running?
    106
    107          @return: C{True} if the session is running, C{False} otherwise
    108          @rtype: C{bool}
    109
    110          """
    111          return self.status == 'R'
    112
    113 -    def get_session_type(self):
    114          """\
    115          Get the session type (i.e. 'D', 'R', 'S' or 'P').
    116
    117          @return: session type
    118          @rtype: C{str}
    119          """
    120          cmd = self.name.split('_')[1]
    121          session_type = cmd[2]
    122          if session_type == 'R' and self.is_published_applications_provider():
    123              session_type = 'P'
    124          return session_type
    125
    126 -    def get_share_mode(self):
    127          """\
    128          Get the share mode of a shadow session.
    129
    130          @return: share mode (0: view-only, 1: full access), C{None} when used for non-desktop-sharing sessions
    131          @rtype: C{str}
    132
    133          """
    134          share_mode = None
    135          cmd = self.name.split('_')[1]
    136          session_type = cmd[2]
    137          if session_type == 'S':
    138              share_mode = cmd[3]
    139          return share_mode
    140
    141 -    def is_suspended(self):
    142          """\
    143          Is this session suspended?
    144
    145          @return: C{True} if the session is suspended, C{False} otherwise
    146          @rtype: C{bool}
    147
    148          """
    149          return self.status == 'S'
    150
    151 -    def is_desktop_session(self):
    152          """\
    153          Is this session a desktop session?
    154
    155          @return: C{True} if this session is a desktop session, C{False} otherwise
    156          @rtype: C{bool}
    157
    158          """
    159          return self.get_session_type() == 'D'
    160
    161 -    def _parse_x2gostartagent_output(self, x2go_output):
    162          """\
    163          Parse x2gostartagent output.
    164
    165          @param x2go_output: output from ,,x2gostartagent'' command (as list of strings/lines)
    166          @type x2go_output: C{list}
    167
    168          """
    169          try:
    170              l = x2go_output.split("\n")
    171              self.name = l[3]
    172              self.cookie = l[1]
    173              self.agent_pid = int(l[2])
    174              self.display = int(l[0])
    175              self.graphics_port = int(l[4])
    176              self.snd_port = int(l[5])
    177              self.sshfs_port = int(l[6])
    178              self.username = ''
    179              self.hostname = ''
    180              # TODO: we have to see how we fill these fields here...
    181              self.date_created = ''
    182              self.date_suspended = ''
    183              # TODO: presume session is running after x2gostartagent, this could be better
    184              self.status = 'R'
    185              self.local_container = ''
    186              self.remote_container = ''
    187          except IndexError, e:
    188              # DEBUGGING CODE
    189              raise e
    190          except ValueError, e:
    191              # DEBUGGING CODE
    192              raise e
    193
    194          # retrieve Telekinesis ports from x2gostartagent output
    195          try:
    196              self.tekictrl_port = int(l[7])
    197          except (IndexError, ValueError), e:
    198              self.tekictrl_port = -1
    199          try:
    200              self.tekidata_port = int(l[8])
    201          except (IndexError, ValueError), e:
    202              self.tekidata_port = -1
    203
    204 -    def initialize(self, x2go_output, username='', hostname='', local_container='', remote_container=''):
    205          """\
    206          Setup a a session info data block, includes parsing of X2Go server's C{x2gostartagent} stdout values.
    207
    208          @param x2go_output: X2Go server's C{x2gostartagent} command output, each value
    209              separated by a newline character.
    210          @type x2go_output: str
    211          @param username: session user name
    212          @type username: str
    213          @param hostname: hostname of X2Go server
    214          @type hostname: str
    215          @param local_container: X2Go client session directory for config files, cache and session logs
    216          @type local_container: str
    217          @param remote_container: X2Go server session directory for config files, cache and session logs
    218          @type remote_container: str
    219
    220          """
    221          self.protect()
    222          self._parse_x2gostartagent_output(x2go_output)
    223          self.username = username
    224          self.hostname = hostname
    225          self.local_container = local_container
    226          self.remote_container = remote_container
    227
    228 -    def protect(self):
    229          """\
    230          Write-protect this session info data structure.
    231
    232          """
    233          self.protected = True
    234
    235 -    def unprotect(self):
    236          """\
    237          Remove write-protection from this session info data structure.
    238
    239          """
    240          self.protected = False
    241
    242 -    def is_protected(self):
    243          """\
    244
    245          """
    246          return self.protected
    247
    248 -    def get_status(self):
    249          """\
    250          Retrieve the session's status from this session info data structure.
    251
    252          @return: session status
    253          @rtype: C{str}
    254
    255          """
    256          return self.status
    257
    258 -    def clear(self):
    259          """\
    260          Clear all properties of a L{X2GoServerSessionInfo} object.
    261
    262          """
    263          self.name = ''
    264          self.cookie = ''
    265          self.agent_pid = ''
    266          self.display = ''
    267          self.graphics_port = ''
    268          self.snd_port = ''
    269          self.sshfs_port = ''
    270          self.tekictrl_port = ''
    271          self.tekidata_port = ''
    272          self.username = ''
    273          self.hostname = ''
    274          self.date_created = ''
    275          self.date_suspended = ''
    276          self.status = ''
    277          self.local_container = ''
    278          self.remote_container = ''
    279          self.protected = False
    280
    281 -    def update(self, session_info):
    282          """\
    283          Update all properties of a L{X2GoServerSessionInfo} object.
    284
    285          @param session_info: a provided session info data structure
    286          @type session_info: C{X2GoServerSessionInfo*}
    287
    288          """
    289          if type(session_info) == type(self):
    290              for prop in ('graphics_port', 'snd_port', 'sshfs_port', 'tekictrl_port', 'tekidata_port', 'date_suspended', 'status', ):
    291                  if hasattr(session_info, prop):
    292                      _new = getattr(session_info, prop)
    293                      _current = getattr(self, prop)
    294                      if _new != _current:
    295                          setattr(self, prop, _new)
    296
    297 -    def __init__(self):
    298          """\
    299          Class constructor, identical to L{clear()} method.
    300
    301          """
    302          self.clear()
    303
    304
    305 -class X2GoServerSessionList(object):
    306      """\
    307      L{X2GoServerSessionList} is used to store all information
    308      that is retrieved from a connected X2Go server on a
    309      C{X2GoControlSession.list_sessions()} call.
    310
    311      """
    312 -    def __init__(self, x2go_output=None, info_backend=X2GoServerSessionInfo):
    313          """\
    314          @param x2go_output: X2Go server's C{x2golistsessions} command output, each
    315              session separated by a newline character. Session values are separated
    316              by Unix Pipe Symbols ('|')
    317          @type x2go_output: str
    318          @param info_backend: the session info backend to use
    319          @type info_backend: C{X2GoServerSessionInfo*}
    320
    321          """
    322          self.sessions = {}
    323          if x2go_output is not None:
    324              lines = x2go_output.split("\n")
    325              for line in lines:
    326                  if not line:
    327                      continue
    328                  s_info = info_backend()
    329                  s_info._parse_x2golistsessions_line(line)
    330                  self.sessions[s_info.name] = s_info
    331
    332 -    def __call__(self):
    333          return self.sessions
    334
    335 -    def set_sessions(self, sessions):
    336          """\
    337          Set the sessions property directly by parsing a complete data structure.
    338
    339          """
    340          self.sessions = sessions
    341
    342 -    def get_session_info(self, session_name):
    343          """\
    344          Retrieve the session information for C{<session_name>}.
    345
    346          @param session_name: the queried session name
    347          @type session_name: C{str}
    348
    349          @return: the session info of C{<session_name>}
    350          @rtype: C{X2GoServerSessionInfo*} or C{None}
    351
    352          """
    353          try:
    354              return self.sessions[session_name]
    355          except KeyError:
    356              return None
    357
    358 -    def get_session_with(self, property_name, value, hostname=None):
    359          """\
    360          Find session with a given display number on a given host.
    361
    362          @param property_name: match a session based on this property name
    363          @type property_name: C{str}
    364          @param value: the resulting session has to match this value for C{<property_name>}
    365          @type value: C{str}
    366          @param hostname: the result has to match this hostname
    367          @type hostname: C{str}
    368
    369          """
    370          if property_name == 'display':
    371              value = value.lstrip(':')
    372              if '.' in value: value = value.split('.')[0]
    373
    374          for session in self.sessions.values():
    375              try:
    376                  if str(getattr(session, property_name)) == str(value):
    377                      if hostname is None or session.hostname == hostname:
    378                          return session
    379              except AttributeError:
    380                  pass
    381