Package default_cfg_fkie :: Module screen_handler
[frames] | no frames]

Source Code for Module default_cfg_fkie.screen_handler

  1  # Software License Agreement (BSD License) 
  2  # 
  3  # Copyright (c) 2012, Fraunhofer FKIE/US, Alexander Tiderko 
  4  # All rights reserved. 
  5  # 
  6  # Redistribution and use in source and binary forms, with or without 
  7  # modification, are permitted provided that the following conditions 
  8  # are met: 
  9  # 
 10  #  * Redistributions of source code must retain the above copyright 
 11  #    notice, this list of conditions and the following disclaimer. 
 12  #  * Redistributions in binary form must reproduce the above 
 13  #    copyright notice, this list of conditions and the following 
 14  #    disclaimer in the documentation and/or other materials provided 
 15  #    with the distribution. 
 16  #  * Neither the name of Fraunhofer nor the names of its 
 17  #    contributors may be used to endorse or promote products derived 
 18  #    from this software without specific prior written permission. 
 19  # 
 20  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 21  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 22  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 23  # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 24  # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
 25  # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 26  # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 27  # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 28  # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
 29  # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
 30  # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 31  # POSSIBILITY OF SUCH DAMAGE. 
 32   
 33  import os 
34 35 36 -class ScreenHandlerException(Exception):
37 pass
38
39 40 -class ScreenHandler(object):
41 ''' 42 The class to handle the running screen sessions and create new sessions on 43 start of the ROS nodes. 44 ''' 45 46 LOG_PATH = ''.join([os.environ.get('ROS_LOG_DIR'), os.path.sep]) if os.environ.get('ROS_LOG_DIR') else os.path.join(os.path.expanduser('~'), '.ros/log/') 47 SCREEN = "/usr/bin/screen" 48 SLASH_SEP = '_' 49 50 @classmethod
51 - def createSessionName(cls, node=None):
52 ''' 53 Creates a name for the screen session. All slash separators are replaced by 54 L{SLASH_SEP} 55 @param node: the name of the node 56 @type node: C{str} 57 @return: name for the screen session. 58 @rtype: C{str} 59 ''' 60 # package_name = str(package) if not package is None else '' 61 # lanchfile_name = str(launchfile).replace('.launch', '') if not launchfile is None else '' 62 node_name = str(node).replace('/', cls.SLASH_SEP) if node is not None else '' 63 # result = ''.join([node_name, '.', package_name, '.', lanchfile_name]) 64 return node_name
65 66 @classmethod
67 - def splitSessionName(cls, session):
68 ''' 69 Splits the screen session name into PID and session name generated by 70 L{createSessionName()}. 71 @param session: the screen session name 72 @type session: C{str} 73 @return: PID, session name generated by L{createSessionName()}. Not presented 74 values are coded as empty strings. Not valid session names have an empty 75 PID string. 76 @rtype: C{str, str} 77 ''' 78 result = session.split('.', 1) 79 if len(result) != 2: 80 return '', '' 81 pid = result[0] 82 node = result[1] # .replace(cls.SLASH_SEP, '/') 83 # package = result[2] 84 # launch = ''.join([result[3], '.launch']) if len(result[2]) > 0 else result[2] 85 return pid, node # , package, launch
86 87 @classmethod
88 - def testScreen(cls):
89 ''' 90 Tests for whether the SCREEN binary exists and raise an exception if not. 91 @raise ScreenHandlerException: if the screen binary not found. 92 ''' 93 if not os.path.isfile(cls.SCREEN): 94 raise ScreenHandlerException(''.join([cls.SCREEN, " is missing"]))
95 96 @classmethod
97 - def getScreenLogFile(cls, session=None, node=None):
98 ''' 99 Generates a log file name of the ROS log. 100 @param node: the name of the node 101 @type node: C{str} 102 @return: the ROS log file name 103 @rtype: C{str} 104 @todo: get the run_id from the ROS parameter server and search in this log folder 105 for the log file (handle the node started using a launch file). 106 ''' 107 if session is not None: 108 return "%s%s.log" % (cls.LOG_PATH, session) 109 elif node is not None: 110 return "%s%s.log" % (cls.LOG_PATH, cls.createSessionName(node)) 111 else: 112 return "%s%s.log" % (cls.LOG_PATH, 'unknown')
113 114 @classmethod
115 - def getROSLogFile(cls, node):
116 ''' 117 Generates a log file name for the ROS log 118 @param node: the name of the node 119 @type node: C{str} 120 @return: the log file name 121 @rtype: C{str} 122 ''' 123 if node is not None: 124 return "%s%s.log" % (cls.LOG_PATH, node.strip('/').replace('/', '_')) 125 else: 126 return ''
127 128 @classmethod
129 - def getScreenCfgFile(cls, session=None, node=None):
130 ''' 131 Generates a configuration file name for the screen session. 132 @param session: the name of the screen session 133 @type session: C{str} 134 @return: the configuration file name 135 @rtype: C{str} 136 ''' 137 if session is not None: 138 return "%s%s.conf" % (cls.LOG_PATH, session) 139 elif node is not None: 140 return "%s%s.log" % (cls.LOG_PATH, cls.createSessionName(node)) 141 else: 142 return "%s%s.log" % (cls.LOG_PATH, 'unknown')
143 144 @classmethod
145 - def getScreenPidFile(cls, session=None, node=None):
146 ''' 147 Generates a PID file name for the screen session. 148 @param session: the name of the screen session 149 @type session: C{str} 150 @return: the PID file name 151 @rtype: C{str} 152 ''' 153 if session is not None: 154 return "%s%s.pid" % (cls.LOG_PATH, session) 155 elif node is not None: 156 return "%s%s.pid" % (cls.LOG_PATH, cls.createSessionName(node)) 157 else: 158 return "%s%s.pid" % (cls.LOG_PATH, 'unknown')
159 160 @classmethod
161 - def getSceenCmd(cls, node):
162 ''' 163 Generates a configuration file and return the command prefix to start the given node 164 in a screen terminal. 165 @param node: the name of the node 166 @type node: C{str} 167 @return: the command prefix 168 @rtype: C{str} 169 ''' 170 filename = cls.getScreenCfgFile(node=node) 171 f = None 172 try: 173 f = open(cls.getScreenCfgFile(node=node), 'w') 174 except Exception: 175 os.makedirs(os.path.dirname(filename)) 176 f = open(cls.getScreenCfgFile(node=node), 'w') 177 f.write(''.join(["logfile ", cls.getScreenLogFile(node=node), "\n"])) 178 f.write("logfile flush 0\n") 179 f.write("defscrollback 10000\n") 180 ld_library_path = os.getenv('LD_LIBRARY_PATH', '') 181 if ld_library_path: 182 f.write(' '.join(['setenv', 'LD_LIBRARY_PATH', ld_library_path, "\n"])) 183 ros_etc_dir = os.getenv('ROS_ETC_DIR', '') 184 if ros_etc_dir: 185 f.write(' '.join(['setenv', 'ROS_ETC_DIR', ros_etc_dir, "\n"])) 186 f.close() 187 return ' '.join([cls.SCREEN, '-c', cls.getScreenCfgFile(node=node), '-L', '-dmS', cls.createSessionName(node=node)])
188