/usr/lib/python2.7/dist-packages/roswtf/environment.py is in python-roswtf 1.11.16-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | # Software License Agreement (BSD License)
#
# Copyright (c) 2009, Willow Garage, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of Willow Garage, Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# Revision $Id$
"""
Rules for checking ROS environment state.
"""
import os
import socket
import stat
import string
import sys
from os.path import isdir, isfile
from roswtf.rules import warning_rule, error_rule
#TODO: unit tests
def paths(path):
"""
@return: paths contained in path variable. path must conform to OS
conventions for path separation (i.e. colon-separated on Unix)
@rtype: [str]
"""
if path:
return path.split(os.pathsep)
return []
def is_executable(path):
"""
@return: True if path has executable permissions
@rtype: bool
"""
mode = os.stat(path)[stat.ST_MODE]
return mode & (stat.S_IXUSR|stat.S_IXGRP|stat.S_IXOTH)
try:
from urllib.parse import urlparse #Python 3
except ImportError:
from urlparse import urlparse #Python 2
def invalid_url(url):
"""
@return: error message if \a url is not a valid url. \a url is
allowed to be empty as that check is considered separately.
@rtype: str
"""
if not url:
return #caught by different rule
p = urlparse(url)
if p[0] != 'http':
return "protocol is not 'http'"
if not p[1]:
return "address is missing"
if not ':' in p[1]:
return "port number is missing"
try:
splits = p[1].split(':')
if len(splits) != 2:
return "invalid address string [%s]"%p[1]
int(splits[1])
except ValueError:
return "port number [%s] is invalid"%(splits[1])
# Error-checking functions for more advanced checks
def ros_root_check(ctx, ros_root=None):
"""
@param ros_root: override ctx, useful for when ctx is not created yet
@type ros_root: str
"""
if ros_root is not None:
path = ros_root
else:
path = ctx.ros_root
if os.path.basename(os.path.normpath(path)) not in ['ros', 'rosbuild']:
return "ROS_ROOT [%s] must end in directory named 'ros'"%path
def _writable_dir_check(ctx, path, name):
"""
If path is not None, validate that it is a writable directory
"""
if path is None:
return
if isfile(path):
return "%s [%s] must point to a directory, not a file"%(name, path)
if not os.access(path, os.W_OK):
return "%s [%s] is not writable"%(name, path)
def ros_home_check(ctx):
return _writable_dir_check(ctx, ctx.env.get('ROS_HOME', None), 'ROS_HOME')
def ros_log_dir_check(ctx):
return _writable_dir_check(ctx, ctx.env.get('ROS_LOG_DIR', None), 'ROS_LOG_DIR')
def ros_test_results_dir_check(ctx):
return _writable_dir_check(ctx, ctx.env.get('ROS_TEST_RESULTS_DIR', None), 'ROS_TEST_RESULTS_DIR')
def pythonpath_check(ctx):
# used to have a lot more checks here, but trying to phase out need for roslib on custom PYTHONPATH
path = ctx.pythonpath
roslib_count = len(set([p for p in paths(path) if 'roslib' in p]))
if roslib_count > 1:
return "Multiple roslib directories in PYTHONPATH (there should only be one)"
def rosconsole_config_file_check(ctx):
if 'ROSCONSOLE_CONFIG_FILE' in ctx.env:
return not isfile(ctx.env['ROSCONSOLE_CONFIG_FILE'])
def path_check(ctx):
# rosdeb setup can clobber local ros stuff, so try and detect this
path = ctx.env['PATH']
idx = path.find('/usr/bin')
if idx < 0:
return
if os.path.exists('/usr/lib/ros/'):
rr_idx = path.find(ctx.ros_root)
if rr_idx > -1 and rr_idx > idx:
return True
def ros_master_uri_hostname(ctx):
uri = ctx.ros_master_uri
parsed = urlparse(uri)
p = urlparse(uri)
if not p[1]:
return #caught by different rule
if not ':' in p[1]:
return #caught by different rule
try:
splits = p[1].split(':')
if len(splits) != 2:
return #caught by different rule
#TODO IPV6: only check for IPv6 when IPv6 is enabled
socket.getaddrinfo(splits[0], 0, 0, 0, socket.SOL_TCP)
except socket.gaierror:
return "Unknown host %s"%splits[0]
# Error/Warning Rules
environment_warnings = [
(path_check,
"PATH has /usr/bin set before ROS_ROOT/bin, which can cause problems as there is system install of ROS on this machine. You may wish to put ROS_ROOT/bin first"),
(lambda ctx: ctx.ros_package_path is None,
"ROS_PACKAGE_PATH is not set. This is not required, but is unusual"),
(lambda ctx: len(paths(ctx.ros_package_path)) == 0,
"ROS_PACKAGE_PATH is empty. This is not required, but is unusual"),
(lambda ctx: not ctx.ros_master_uri,
"ROS_MASTER_URI is empty. This is not required, but is unusual"),
(ros_master_uri_hostname,
"Cannot resolve hostname in ROS_MASTER_URI [%(ros_master_uri)s]"),
(rosconsole_config_file_check,
"ROS_CONSOLE_CONFIG_FILE does not point to an existing file"),
]
environment_errors = [
# ROS_ROOT
(lambda ctx: not isdir(ctx.ros_root),
"ROS_ROOT [%(ros_root)s] does not point to a directory"),
(ros_root_check,
"ROS_ROOT is invalid: "),
# ROS_PACKAGE_PATH
(lambda ctx: [d for d in paths(ctx.ros_package_path) if d and isfile(d)],
"Path(s) in ROS_PACKAGE_PATH [%(ros_package_path)s] points to a file instead of a directory: "),
(lambda ctx: [d for d in paths(ctx.ros_package_path) if d and not isdir(d) and not (os.path.basename(d) == 'stacks' and os.path.exists(os.path.join(os.path.dirname(d), '.catkin')))],
"Not all paths in ROS_PACKAGE_PATH [%(ros_package_path)s] point to an existing directory: "),
# PYTHONPATH
(lambda ctx: [d for d in paths(ctx.pythonpath) if d and not isdir(d)],
"Not all paths in PYTHONPATH [%(pythonpath)s] point to a directory: "),
(pythonpath_check,
"PYTHONPATH [%(pythonpath)s] is invalid: "),
# ROS_HOME, ROS_LOG_DIR, ROS_TEST_RESULTS_DIR
(ros_home_check, "ROS_HOME is invalid: "),
(ros_log_dir_check, "ROS_LOG_DIR is invalid: "),
(ros_test_results_dir_check, "ROS_TEST_RESULTS_DIR is invalid: "),
(lambda ctx: invalid_url(ctx.ros_master_uri),
"ROS_MASTER_URI [%(ros_master_uri)s] is not a valid URL: "),
]
def wtf_check_environment(ctx):
#TODO: check ROS_BOOST_ROOT
for r in environment_warnings:
warning_rule(r, r[0](ctx), ctx)
for r in environment_errors:
error_rule(r, r[0](ctx), ctx)
|