def test_get_cwd(self): test_path = '/this/is/path/to' result_path = get_cwd('node', '%s/bin' % test_path) self.assertEqual( test_path, result_path, "wrong get_cwd from 'node' type, expected: %s, got: %s" % (test_path, result_path)) test_path = os.getcwd() result_path = get_cwd('cwd', '') self.assertEqual( test_path, result_path, "wrong get_cwd from 'cwd' type, expected: %s, got: %s" % (test_path, result_path)) test_path = rospkg.get_ros_root() result_path = get_cwd('ros-root', '') self.assertEqual( test_path, result_path, "wrong get_cwd from 'ros-root' type, expected: %s, got: %s" % (test_path, result_path)) test_path = rospkg.get_ros_home() result_path = get_cwd('', '') self.assertEqual( test_path, result_path, "wrong get_cwd from empty type, expected: %s, got: %s" % (test_path, result_path))
def bc_run_node(cls, name, grpc_path='grpc://localhost:12321', masteruri='', reload_global_param=False, loglevel='', logformat='', auto_pw_request=False, user=None, pw=None): ''' Start the node with given name from the given configuration. :param runcfg: the configuration containing the start parameter :type runcfg: AdvRunCfg :raise StartException: if the screen is not available on host. :raise Exception: on errors while resolving host :see: :meth:`fkie_node_manager.is_local()` ''' startcfg = nm.nmd().launch.get_start_cfg( name, grpc_path, masteruri, reload_global_param=reload_global_param, loglevel=loglevel, logformat=logformat) new_env = dict(startcfg.env) # set logging options if startcfg.namespace: new_env['ROS_NAMESPACE'] = startcfg.namespace # set logging if startcfg.logformat: new_env['ROSCONSOLE_FORMAT'] = '%s' % startcfg.logformat # if startcfg.loglevel: # new_env['ROSCONSOLE_CONFIG_FILE'] = launcher._rosconsole_cfg_file(startcfg.package, startcfg.loglevel) args = [] # set name and namespace of the node if startcfg.name: args.append("__name:=%s" % startcfg.name) if startcfg.namespace: args.append("__ns:=%s" % startcfg.namespace) # add remap arguments for key, val in startcfg.remaps.items(): args.append("%s:=%s" % (key, val)) # handle respawn if startcfg.respawn: if startcfg.respawn_delay > 0: new_env['RESPAWN_DELAY'] = '%d' % startcfg.respawn_delay respawn_params = launcher._get_respawn_params( startcfg.fullname, startcfg.params) if respawn_params['max'] > 0: new_env['RESPAWN_MAX'] = '%d' % respawn_params['max'] if respawn_params['min_runtime'] > 0: new_env['RESPAWN_MIN_RUNTIME'] = '%d' % respawn_params[ 'min_runtime'] if startcfg.cwd: cwd = get_cwd(startcfg.cwd, startcfg.binary_path) if cwd: args.append('__cwd:=%s' % cwd) # check for masteruri masteruri = startcfg.masteruri on_hostname = startcfg.hostname if masteruri is None: masteruri = masteruri_from_ros() if masteruri is not None: new_env['ROS_MASTER_URI'] = masteruri if 'ROS_HOSTNAME' in os.environ: # set only ROS_HOSTNAME if node manager have also one ros_hostname = nmdhost.get_ros_hostname(masteruri, on_hostname) if ros_hostname: new_env['ROS_HOSTNAME'] = ros_hostname # load params to ROS master launcher._load_parameters(masteruri, startcfg.params, startcfg.clear_params) abs_paths = list() # tuples of (parameter name, old value, new value) not_found_packages = list() # package names # # set the global parameter # if runcfg.masteruri is not None and runcfg.masteruri not in runcfg.roslaunch_config.global_param_done: # global_node_names = cls.getGlobalParams(runcfg.roslaunch_config.Roscfg) # rospy.loginfo("Register global parameter:\n %s", '\n '.join("%s%s" % (utf8(v)[:80], '...' if len(utf8(v)) > 80 else'') for v in global_node_names.values())) # abs_paths[len(abs_paths):], not_found_packages[len(not_found_packages):] = cls._load_parameters(runcfg.masteruri, global_node_names, [], runcfg.user, runcfg.pw, runcfg.auto_pw_request) # runcfg.roslaunch_config.global_param_done.append(runcfg.masteruri) # # # add params # if runcfg.masteruri is not None: # nodens = ''.join([n.namespace, n.name, rospy.names.SEP]) # params = dict() # for param, value in runcfg.roslaunch_config.Roscfg.params.items(): # if param.startswith(nodens): # params[param] = value # clear_params = [] # for cparam in runcfg.roslaunch_config.Roscfg.clear_params: # if cparam.startswith(nodens): # clear_params.append(cparam) # rospy.loginfo("Delete parameter:\n %s", '\n '.join(clear_params)) # rospy.loginfo("Register parameter:\n %s", '\n '.join("%s%s" % (utf8(v)[:80], '...' if len(utf8(v)) > 80 else'') for v in params.values())) # abs_paths[len(abs_paths):], not_found_packages[len(not_found_packages):] = cls._load_parameters(runcfg.masteruri, params, clear_params, runcfg.user, runcfg.pw, runcfg.auto_pw_request) if not nm.is_local(on_hostname, wait=True): # start remote if not startcfg.package: raise StartException( "Can't run remote without a valid package name!") # setup environment env_command = '' if new_env: try: for k, v in new_env.items(): v_value, is_abs_path, found, package = cls._bc_resolve_abs_paths( v, on_hostname, auto_pw_request, user, pw) new_env[k] = v_value if is_abs_path: abs_paths.append(('ENV', "%s=%s" % (k, v), "%s=%s" % (k, v_value))) if not found and package: not_found_packages.append(package) env_command = "env " + ' '.join( ["%s=\'%s\'" % (k, v) for (k, v) in new_env.items()]) except nm.AuthenticationRequest as e: raise nm.InteractionNeededError( e, cls.bc_run_node, { 'name': name, 'grpc_path': grpc_path, 'masteruri': masteruri, 'reload_global_param': reload_global_param, 'loglevel': loglevel, 'logformat': logformat, 'auto_pw_request': auto_pw_request, 'user': user, 'pw': pw }) startcmd = [ env_command, nm.settings().start_remote_script, '--package', utf8(startcfg.package), '--node_type', utf8(startcfg.binary), '--node_name', utf8(startcfg.fullname), '--node_respawn true' if startcfg.respawn else '' ] if startcfg.masteruri is not None: startcmd.append('--masteruri') startcmd.append(startcfg.masteruri) if startcfg.prefix: startcmd[len(startcmd):] = ['--prefix', startcfg.prefix] if startcfg.loglevel: startcmd.append('--loglevel') startcmd.append(startcfg.loglevel) # rename the absolute paths in the args of the node node_args = [] error = '' output = '' try: for a in startcfg.args: a_value, is_abs_path, found, package = cls._bc_resolve_abs_paths( a, on_hostname, auto_pw_request, user, pw) node_args.append(a_value) if is_abs_path: abs_paths.append(('ARGS', a, a_value)) if not found and package: not_found_packages.append(package) startcmd[len(startcmd):] = node_args startcmd[len(startcmd):] = args rospy.loginfo("Run remote on %s: %s", on_hostname, utf8(' '.join(startcmd))) _, stdout, stderr, ok = nm.ssh().ssh_exec(on_hostname, startcmd, user, pw, auto_pw_request, close_stdin=True) output = stdout.read() error = stderr.read() stdout.close() stderr.close() except nm.AuthenticationRequest as e: raise nm.InteractionNeededError( e, cls.bc_run_node, { 'name': name, 'grpc_path': grpc_path, 'masteruri': masteruri, 'reload_global_param': reload_global_param, 'loglevel': loglevel, 'logformat': logformat, 'auto_pw_request': auto_pw_request, 'user': user, 'pw': pw }) if ok: if error: rospy.logwarn("ERROR while start '%s': %s", startcfg.fullname, error) raise StartException( utf8(''.join( ['The host "', on_hostname, '" reports:\n', error]))) if output: rospy.logdebug("STDOUT while start '%s': %s", startcfg.fullname, output) # inform about absolute paths in parameter value if len(abs_paths) > 0: rospy.loginfo( "Absolute paths found while start:\n%s", utf8('\n'.join([ ''.join([p, '\n OLD: ', ov, '\n NEW: ', nv]) for p, ov, nv in abs_paths ]))) if len(not_found_packages) > 0: packages = '\n'.join(not_found_packages) raise StartException( utf8('\n'.join([ 'Some absolute paths are not renamed because following packages are not found on remote host:', packages ])))