diff --git a/.devcontainer/README.rst b/.devcontainer/README.rst new file mode 100644 index 000000000..6afe46c8d --- /dev/null +++ b/.devcontainer/README.rst @@ -0,0 +1,78 @@ +Development Container for ROS2 Rust +==================================== + +This repository includes a pre-configured development container setup, designed to facilitate working on ROS2 Rust projects. The setup is managed using Visual Studio Code's DevContainers feature. + +.. contents:: Table of Contents + :depth: 3 + :local: + +File Description +---------------- + +The provided ``devcontainer.json`` file specifies the configuration for running a containerized development environment with the following features: + +- **Image Configuration**: Uses the Docker image ``ros2_rust_dev:latest``. +- **Build Settings**: + - Context: Specifies the root directory of the project (``..``). + - Dockerfile: Uses the Dockerfile located at ``../docker/Dockerfile``. + - Build Args: Includes runtime environment variables such as ``XDG_RUNTIME_DIR``. +- **Workspace**: + - Mounts the folder ``/home/cuser/workspace`` as the development workspace. +- **Container Runtime**: + - Enables ``--network=host`` for network sharing. + - Grants privileged access using ``--privileged``. +- **Environment Variables**: + - ``DISPLAY`` and ``TERM`` are forwarded from the host to the container to support GUI applications and terminal colors. +- **User Settings**: + - The development container runs as the user ``cuser``. + - Configures the shell to use ``/bin/bash`` for a familiar and customizable command-line experience. + +Setting Up and Running the DevContainer in VS Code +-------------------------------------------------- + +To use this development container in Visual Studio Code, follow these steps: + +Prerequisites +~~~~~~~~~~~~~ + +1. **Install VS Code**: Download and install `Visual Studio Code `__. + +2. **Install Required Extensions:** + - `Remote Containers `__ +3. **Install Docker:** Ensure Docker is installed and running on your system. You can download Docker from `here `__. + + +Steps to Launch the DevContainer +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +1. **Clone the Repository**: Clone your project repository to your local machine. + +.. code-block:: bash + + $ git clone git@github.com:ros2-rust/ros2_rust.git + $ cd ros2_rust + + + +2. **Open in VS Code**: Open the repository folder in VS Code. + +.. code-block:: bash + + $ code . + +3. **Open the Command Palette**: Press ``Ctrl+Shift+P`` (Windows/Linux) or ``Cmd+Shift+P`` (macOS) to open the Command Palette. +4. **Reopen in Container**: Search for and select **"Dev Containers: Reopen in Container"**. VS Code will build and start the development container based on the configuration in ``devcontainer.json``. +5. **Start Coding**: Once the container is running, your workspace is ready for development. You can open terminals, run commands, and debug your ROS2 Rust projects seamlessly within the containerized environment. + +Notes +~~~~~ + +- **Container Network**: The ``--network=host`` option is enabled to allow network sharing between the host and container. +- **Privilege**: The ``--privileged`` flag is enabled, which may be required for specific ROS2 features but should be used cautiously. +- If you encounter permission issues with X11, ensure the host system is configured to allow access in the vscode: + +.. code-block:: bash + + $ xhost local:root + $ code & \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..53f002fff --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,27 @@ + +{ + "name": "ros2_rust_dev:latest", + "build": { + "context": "..", + "dockerfile": "../docker/Dockerfile", + "args": { + "XDG_RUNTIME_DIR": "${localEnv:XDG_RUNTIME_DIR}" + } + }, + "workspaceFolder": "/home/cuser/workspace", + "runArgs": [ + "--network=host", + "--privileged" + ], + "containerEnv": { + "DISPLAY": "${localEnv:DISPLAY}", + "TERM": "xterm-256color" + }, + + "remoteUser": "cuser", + "containerEnv": { + // Convenience, for shell colors, aliases, etc + "SHELL": "/bin/bash" + } + +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index ede9821ea..db9a33606 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,23 @@ ARG ROS_DISTRO=humble -FROM ros:$ROS_DISTRO as base +FROM ros:$ROS_DISTRO AS base ARG DEBIAN_FRONTEND=noninteractive +ARG CONTAINER_USER="cuser" +ARG USER_UID=1000 +ARG USER_GID=$USER_UID + +# Create a user in the container to operate as unprivileged +RUN groupadd --gid $USER_GID $CONTAINER_USER \ + && useradd --uid $USER_UID --gid $USER_GID -m $CONTAINER_USER \ + && mkdir -p /home/$CONTAINER_USER +RUN apt-get update \ + && apt-get install -y sudo \ + && rm -rf /var/lib/apt/lists/* \ + && echo $CONTAINER_USER ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$CONTAINER_USER \ + && chmod 0440 /etc/sudoers.d/$CONTAINER_USER + +SHELL ["/bin/bash", "--login", "-c"] + # Install dependencies RUN apt-get update && apt-get install -y \ curl \ @@ -11,14 +27,18 @@ RUN apt-get update && apt-get install -y \ python3-pip \ && rm -rf /var/lib/apt/lists/* + # Install Rust +USER $CONTAINER_USER +WORKDIR /home/${CONTAINER_USER} RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --default-toolchain 1.75.0 -y ENV PATH=/root/.cargo/bin:$PATH + RUN pip install --upgrade pytest # Install the colcon-cargo and colcon-ros-cargo plugins RUN pip install git+https://github.com/colcon/colcon-cargo.git git+https://github.com/colcon/colcon-ros-cargo.git -RUN mkdir -p /workspace && echo "Did you forget to mount the repository into the Docker container?" > /workspace/HELLO.txt -WORKDIR /workspace +RUN mkdir -p ~/workspace && echo "Did you forget to mount the repository into the Docker container?" > ~/workspace/HELLO.txt +WORKDIR /home/${CONTAINER_USER}/workspace diff --git a/README.md b/README.md index cee8a9b8e..e5914ffb9 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ sudo apt install -y git libclang-dev python3-pip python3-vcstool # libclang-dev pip install git+https://github.com/colcon/colcon-cargo.git pip install git+https://github.com/colcon/colcon-ros-cargo.git -mkdir -p workspace/src && cd workspace +mkdir -p ~/workspace/src && cd ~/workspace git clone https://github.com/ros2-rust/ros2_rust.git src/ros2_rust vcs import src < src/ros2_rust/ros2_rust_humble.repos . /opt/ros/humble/setup.sh diff --git a/docker/README.rst b/docker/README.rst new file mode 100644 index 000000000..b424a0825 --- /dev/null +++ b/docker/README.rst @@ -0,0 +1,91 @@ +ROS2 Rust Docker Environment +========================================================= + +This folder contains scripts to build, start, and interact with a Docker container for a ROS2 Rust environment. + +.. contents:: Table of Contents + :depth: 3 + :local: + +Prerequisites +------------- + +Ensure you have the following installed on your system: + +- `Docker `__ +- Permissions to run Docker commands (sudo may be required on some systems). + + + +Files in the Folder +------------------- + +- `build.sh <./build.sh>`_: Builds the Docker image. +- `start.sh <./start.sh>`_: Starts the Docker container. +- `shell.sh <./shell.sh>`_: Accesses the running container + + +Steps to Use +------------ + +1. Build the Docker Image +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Run the ``build.sh`` script to build the Docker image: + +.. code-block:: bash + + $ ./build.sh + +This script: + +- Builds a Docker image named ``ros2_rust:latest``. +- Uses ``BUILDKIT`` for efficient caching and builds. + + +2. Start the Docker Container +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Run the ``start.sh`` script to start the container: + +.. code-block:: bash + + $ ./start.sh + +This script: + +- Checks if a container based on the ros2_rust image exists and removes it if necessary. +- Starts a new container named ros2_rust with the following settings: + - **Interactive mode** (``-it``). + - **User ID Mapping**: Maps the current user (ID ``1000``) to the container user cuser. + - **Privileges**: Grants ``sudo`` group membership and system capabilities (e.g., sys_nice). + - **Networking**: Uses the host's network stack. + - **X11 Forwarding**: Allows graphical applications to be displayed on the host system. + + +3. Access the Running Container +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Run the ``shell.sh`` script to open an interactive shell in the running container: + +.. code-block:: bash + + $ ./shell.sh + +This script: + +- Opens a Bash shell as the user ``cuser``. +- Sets the working directory to ``/home/cuser/workspace``. + + +4. Install ros2 rust packages +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Follow the `README.md <../README.md>`_ file to install the overall packages needed to start working with ROS2 and Rust. + + +Notes +----- +- If you encounter permission issues with X11, ensure the host system is configured to allow access in each terminal: + +.. code-block:: bash + + $ xhost local:root \ No newline at end of file diff --git a/docker/build.sh b/docker/build.sh new file mode 100755 index 000000000..ab8ae94f4 --- /dev/null +++ b/docker/build.sh @@ -0,0 +1,6 @@ +echo -e "Building ros2_rust:lastest image" +name=ros2_rust +DOCKER_BUILDKIT=1 \ +docker build --pull --rm -f ../Dockerfile \ +--build-arg BUILDKIT_INLINE_CACHE=1 \ +--tag $name:latest . \ No newline at end of file diff --git a/docker/shell.sh b/docker/shell.sh new file mode 100755 index 000000000..fd6fa928e --- /dev/null +++ b/docker/shell.sh @@ -0,0 +1,2 @@ +NAME=ros2_rust +exec docker exec -it $NAME sudo -u cuser -i /bin/bash -c "cd ~/workspace && exec /bin/bash" \ No newline at end of file diff --git a/docker/start.sh b/docker/start.sh new file mode 100755 index 000000000..e6a8f0d17 --- /dev/null +++ b/docker/start.sh @@ -0,0 +1,29 @@ +CUSER_ID="1000" +CONTAINER_USER="cuser" + +IMAGE_NAME=ros2_rust + +# Check if there are any containers created from the image +CONTAINERS=$(docker ps -a --filter "ancestor=$IMAGE_NAME" -q) + +if [ -n "$CONTAINERS" ]; then + echo "Image has been used to start a container. Removing it." + docker stop $IMAGE_NAME + docker rm -f $IMAGE_NAME +else + echo "Image has not been started. Skipping removal." +fi + +echo -e "Starting up ros2_rust container \n >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + +docker run -it --privileged \ + --user=${CUSER_ID}:${CUSER_ID}\ + --group-add sudo \ + --env="DISPLAY" \ + --env="QT_X11_NO_MITSHM=1" \ + --workdir="/home/${CONTAINER_USER}/workspace" \ + --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \ + --net=host \ + --cap-add=sys_nice \ + --name=$IMAGE_NAME \ + $IMAGE_NAME \ \ No newline at end of file