Example #1
0
 def __init__(self, args):
     self._args = args
     self._proxy = ServerProxy(
         'http://localhost:%d/%s/' %
         (get_daemon_port(), rclpy.get_rmw_implementation_identifier()),
         allow_none=True)
     self._methods = []
Example #2
0
def main(*, argv=None):
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument(
        '--rmw-implementation',
        type=str,
        required=True,
        help='The RMW implementation name (must match the return value of '
        'rclpy.get_rmw_implementation_identifier())')
    parser.add_argument(
        '--ros-domain-id',
        metavar='N',
        type=int,
        required=True,
        help='The ROS domain id (must match the environment variable '
        'ROS_DOMAIN_ID)')
    parser.add_argument(
        '--timeout',
        metavar='N',
        type=int,
        default=2 * 60 * 60,
        help='Shutdown the daemon after N seconds of inactivity')
    args = parser.parse_args(args=argv)

    # the arguments are only passed for visibility in e.g. the process list
    assert args.rmw_implementation == rclpy.get_rmw_implementation_identifier()
    assert args.ros_domain_id == get_ros_domain_id()

    serve(make_xmlrpc_server(), timeout=args.timeout)
Example #3
0
def spawn_daemon(args, wait_until_spawned=None, debug=False):
    ros_domain_id = int(os.environ.get('ROS_DOMAIN_ID', 0))
    kwargs = {}
    if platform.system() != 'Windows':
        cmd = ['_ros2_daemon']
    else:
        # allow closing the shell the daemon was spawned from
        # while the daemon is still running
        cmd = [
            sys.executable,
            os.path.join(os.path.dirname(os.path.dirname(__file__)),
                         'daemon/__init__.py')
        ]
        # Process Creation Flag documented in the MSDN
        DETACHED_PROCESS = 0x00000008  # noqa: N806
        kwargs.update(creationflags=DETACHED_PROCESS)
        # avoid showing cmd windows for subprocess
        si = subprocess.STARTUPINFO()
        si.dwFlags = subprocess.STARTF_USESHOWWINDOW
        si.wShowWindow = subprocess.SW_HIDE
        kwargs['startupinfo'] = si
        # don't keep handle of current working directory in daemon process
        kwargs.update(cwd=os.environ.get('SYSTEMROOT', None))

    rmw_implementation_identifier = rclpy.get_rmw_implementation_identifier()
    if rmw_implementation_identifier is None:
        raise RuntimeError('Unable to get rmw_implementation_identifier, '
                           'try specifying the implementation to use via the '
                           "'RMW_IMPLEMENTATION' environment variable")
    cmd.extend([
        # the arguments are only passed for visibility in e.g. the process list
        '--rmw-implementation',
        rmw_implementation_identifier,
        '--ros-domain-id',
        str(ros_domain_id)
    ])
    if not debug:
        kwargs['stdout'] = subprocess.DEVNULL
        kwargs['stderr'] = subprocess.DEVNULL
    subprocess.Popen(cmd, **kwargs)

    if wait_until_spawned is None:
        return True

    if wait_until_spawned > 0.0:
        timeout = time.time() + wait_until_spawned
    else:
        timeout = None
    while True:
        if is_daemon_running(args):
            return True
        time.sleep(0.1)
        if timeout is not None and time.time() >= timeout:
            return None
def test_create_permission(enclave_dir):
    assert enclave_dir.joinpath('permissions.xml').is_file()
    assert enclave_dir.joinpath('permissions.p7s').is_file()

    tree = lxml.etree.parse(str(enclave_dir.joinpath('permissions.xml')))

    # Validate the schema
    permissions_xsd_path = get_transport_schema('dds', 'permissions.xsd')
    permissions_xsd = lxml.etree.XMLSchema(
        lxml.etree.parse(permissions_xsd_path))
    permissions_xsd.assertValid(tree)

    dds = tree.getroot()
    assert dds.tag == 'dds'

    permissions = list(dds.iterchildren(tag='permissions'))
    assert len(permissions) == 1

    grants = list(permissions[0].iterchildren(tag='grant'))
    assert len(grants) == 1
    assert grants[0].get('name') == _test_identity

    allow_rules = list(grants[0].iterchildren(tag='allow_rule'))
    if rclpy.get_rmw_implementation_identifier(
    ) in _permission._RMW_WITH_ROS_GRAPH_INFO_TOPIC:
        assert len(allow_rules) == 2
    else:
        assert len(allow_rules) == 1

    publish_rules = list(allow_rules[0].iterchildren(tag='publish'))
    assert len(publish_rules) == 1

    subscribe_rules = list(allow_rules[0].iterchildren(tag='subscribe'))
    assert len(subscribe_rules) == 1

    published_topics_set = list(publish_rules[0].iterchildren(tag='topics'))
    assert len(published_topics_set) == 1
    published_topics = [
        c.text for c in published_topics_set[0].iterchildren(tag='topic')
    ]
    assert len(published_topics) > 0

    subscribed_topics_set = list(subscribe_rules[0].iterchildren(tag='topics'))
    assert len(subscribed_topics_set) == 1
    subscribed_topics = [
        c.text for c in subscribed_topics_set[0].iterchildren(tag='topic')
    ]
    assert len(subscribed_topics) > 0

    # Verify that publication is allowed on chatter, but not subscription
    assert 'rt/chatter' in published_topics
    assert 'rt/chatter' not in subscribed_topics
def func_import_each_available_rmw_implementation(rmw_implementation):
    import rclpy
    from rclpy.impl.rmw_implementation_tools import get_rmw_implementations
    from rclpy.impl.rmw_implementation_tools import select_rmw_implementation

    rmw_implementations = get_rmw_implementations()
    assert(rmw_implementation in rmw_implementations)

    select_rmw_implementation(rmw_implementation)
    rclpy.init([])

    set_rmw = rclpy.get_rmw_implementation_identifier()

    assert set_rmw == rmw_implementation, \
        "expected '{0}' but got '{1}'".format(
            rmw_implementation, set_rmw)
    return ctypes.c_bool(True)
Example #6
0
def spawn_daemon(args, timeout=None, debug=False):
    """
    Spawn daemon node if it's not running.

    To avoid TOCTOU races, this function instantiates
    the XMLRPC server (binding the socket in the process)
    and transfers it to the daemon process through pipes
    (sending the inheritable socket with it). In a sense,
    the socket functionally behaves as a mutex.

    :param args: `DaemonNode` arguments namespace.
    :param timeout: optional duration, in seconds, to wait
      until the daemon node is ready. Non-positive
      durations will result in an indefinite wait.
    :param debug: if `True`, the daemon process will output
      to the current `stdout` and `stderr` streams.
    :return: `True` if the the daemon was spawned,
      `False` if it was already running.
    :raises: if it fails to spawn the daemon.
    """
    # Acquire socket by instantiating XMLRPC server.
    try:
        server = daemon.make_xmlrpc_server()
        server.socket.set_inheritable(True)
    except socket.error as e:
        if e.errno == errno.EADDRINUSE:
            # Failed to acquire socket
            # Daemon already running
            return False
        raise

    # Transfer XMLRPC server to daemon (and the socket with it).
    try:
        tags = {
            'name': 'ros2-daemon', 'ros_domain_id': get_ros_domain_id(),
            'rmw_implementation': rclpy.get_rmw_implementation_identifier()}

        daemonize(
            functools.partial(daemon.serve, server),
            tags=tags, timeout=timeout, debug=debug)
    finally:
        server.server_close()

    return True
def func_select_rmw_implementation_by_environment(rmw_implementation):
    import rclpy
    from rclpy.impl.rmw_implementation_tools import get_rmw_implementations

    os.environ['RCLPY_IMPLEMENTATION'] = rmw_implementation

    assert('RCLPY_IMPLEMENTATION' in os.environ)

    rmw_implementations = get_rmw_implementations()
    assert(os.environ['RCLPY_IMPLEMENTATION'] in rmw_implementations)

    rclpy.init([])

    set_rmw = rclpy.get_rmw_implementation_identifier()

    assert set_rmw == rmw_implementation, \
        "expected '{0}' but got '{1}'".format(
            rmw_implementation, set_rmw)
    return ctypes.c_bool(True)
Example #8
0
def spawn_daemon(args, wait_until_spawned=None):
    ros_domain_id = int(os.environ.get('ROS_DOMAIN_ID', 0))
    kwargs = {}
    if platform.system() != 'Windows':
        cmd = ['_ros2_daemon']
    else:
        # allow closing the shell the daemon was spawned from
        # while the daemon is still running
        cmd = [
            sys.executable,
            os.path.join(os.path.dirname(os.path.dirname(__file__)),
                         'daemon/__init__.py')
        ]
        # Process Creation Flag documented in the MSDN
        DETACHED_PROCESS = 0x00000008  # noqa: N806
        kwargs.update(creationflags=DETACHED_PROCESS)
        # don't keep handle of current working directory in daemon process
        kwargs.update(cwd=os.environ.get('SYSTEMROOT', None))
    subprocess.Popen(
        cmd + [
            # the arguments are only passed for visibility in e.g. the process list
            '--rmw-implementation',
            rclpy.get_rmw_implementation_identifier(),
            '--ros-domain-id',
            str(ros_domain_id)
        ],
        stdout=subprocess.DEVNULL,
        stderr=subprocess.DEVNULL,
        **kwargs)

    if wait_until_spawned is None:
        return True

    if wait_until_spawned > 0.0:
        timeout = time.time() + wait_until_spawned
    else:
        timeout = None
    while True:
        if is_daemon_running(args):
            return True
        time.sleep(0.1)
        if timeout is not None and time.time() >= timeout:
            return None
def func_import_each_available_rmw_implementation(rmw_implementation):
    import rclpy
    from rclpy.impl.rmw_implementation_tools import get_rmw_implementations
    from rclpy.impl.rmw_implementation_tools import select_rmw_implementation

    rmw_implementations = get_rmw_implementations()
    assert(rmw_implementation in rmw_implementations)

    select_rmw_implementation(rmw_implementation)
    rclpy.init([])

    set_rmw = rclpy.get_rmw_implementation_identifier()

    assert set_rmw in identifiers_map, \
        "expected identifier '{0}' to be in the map '{1}'".format(set_rmw, identifiers_map)

    set_rmw_equivalent = identifiers_map[set_rmw]
    assert set_rmw_equivalent == rmw_implementation, \
        "expected '{0}' but got '{1}' (aka '{2}')".format(
            rmw_implementation, set_rmw_equivalent, set_rmw)
    return ctypes.c_bool(True)
def func_select_rmw_implementation_by_environment(rmw_implementation):
    import rclpy
    from rclpy.impl.rmw_implementation_tools import get_rmw_implementations

    os.environ['RCLPY_IMPLEMENTATION'] = rmw_implementation

    assert('RCLPY_IMPLEMENTATION' in os.environ)

    rmw_implementations = get_rmw_implementations()
    assert(os.environ['RCLPY_IMPLEMENTATION'] in rmw_implementations)

    rclpy.init([])

    set_rmw = rclpy.get_rmw_implementation_identifier()

    assert set_rmw in identifiers_map, \
        "expected identifier '{0}' to be in the map '{1}'".format(set_rmw, identifiers_map)

    set_rmw_equivalent = identifiers_map[set_rmw]
    assert set_rmw_equivalent == rmw_implementation, \
        "expected '{0}' but got '{1}' (aka '{2}')".format(
            rmw_implementation, set_rmw_equivalent, set_rmw)
    return ctypes.c_bool(True)
Example #11
0
def main(*, script_name='_ros2_daemon', argv=None):
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument(
        '--rmw-implementation', type=str, required=True,
        help='The RMW implementation name (must match the return value of '
             'rclpy.get_rmw_implementation_identifier())')
    parser.add_argument(
        '--ros-domain-id', metavar='N', type=int, required=True,
        help='The ROS domain id (must match the environment variable '
             'ROS_DOMAIN_ID)')
    parser.add_argument(
        '--timeout', metavar='N', type=int, default=2 * 60 * 60,
        help='Shutdown the daemon after N seconds of inactivity')
    args = parser.parse_args(args=argv)

    # the arguments are only passed for visibility in e.g. the process list
    assert args.rmw_implementation == rclpy.get_rmw_implementation_identifier()
    assert args.ros_domain_id == int(os.environ.get('ROS_DOMAIN_ID', 0))

    addr = ('localhost', get_daemon_port())
    NodeArgs = namedtuple('NodeArgs', 'node_name_suffix')
    node_args = NodeArgs(node_name_suffix='_daemon_%d' % args.ros_domain_id)
    with DirectNode(node_args) as node:
        server = LocalXMLRPCServer(
            addr, logRequests=False, requestHandler=RequestHandler,
            allow_none=True)

        try:
            server.register_introspection_functions()

            # expose getter functions of node
            server.register_function(
                _print_invoked_function_name(node.get_node_names))
            server.register_function(
                _print_invoked_function_name(node.get_topic_names_and_types))
            server.register_function(
                _print_invoked_function_name(node.get_service_names_and_types))

            shutdown = False

            # shutdown the daemon in case of a timeout
            def timeout_handler():
                nonlocal shutdown
                print('Shutdown due to timeout')
                shutdown = True
            server.handle_timeout = timeout_handler
            server.timeout = args.timeout

            # function to shutdown daemon remotely
            def shutdown_handler():
                nonlocal shutdown
                print('Remote shutdown requested')
                shutdown = True
            server.register_function(shutdown_handler, 'system.shutdown')

            print('Serving XML-RPC on %s:%d/ros2cli/' % (addr[0], addr[1]))
            try:
                while not shutdown:
                    server.handle_request()
            except KeyboardInterrupt:
                pass
        finally:
            server.server_close()
Example #12
0
class RequestHandler(SimpleXMLRPCRequestHandler):
    rpc_paths = ('/%s/' % rclpy.get_rmw_implementation_identifier(), )