diff --git a/exwayz_mapping.dockerfile b/exwayz_mapping.dockerfile new file mode 100644 index 0000000..b871258 --- /dev/null +++ b/exwayz_mapping.dockerfile @@ -0,0 +1,32 @@ +# syntax=docker/dockerfile:1.3 +FROM ros:jazzy-ros-core + +# Build argument provided by buildx/BuildKit: `TARGETARCH` (amd64, arm64, etc.). +# Default to amd64 when not provided. +ARG TARGETARCH=amd64 +ARG GRAPICAL_ENV=TRUE + + +# Install dependencies and setup for GUI applications +ENV DISPLAY=:0 +ENV WAYLAND_DISPLAY=wayland-0 +ENV XDG_SESSION_TYPE=x11 +ENV XDG_RUNTIME_DIR=/mnt/wslg/runtime-dir +#If debug, install the following: +RUN if [ "$GRAPHICAL_ENV" = "TRUE" ]; then \ + apt update && apt install -y libgl1-mesa-dev libosmesa6-dev libglew-dev libgles2-mesa-dev libglfw3-dev libstdc++6 mesa-utils; \ + fi + #TODO we're installing unneccessary things like the humanity-icons package, clean this up later. + + + +mkdir -p ~/ros2_ws/src +pushd ~/ros2_ws +git clone https://github.com/Exwayz-Navigation/exwayz_msgs.git src/exwayz_msgs +colcon build --packages-select exwayz_msgs --parallel-workers 2 +popd + +source $HOME/ros2_ws/install/local_setup.bash #resp. local_setup.zsh + +# Set entrypoint +ENTRYPOINT ["/ros_entrypoint.sh"] diff --git a/exwayz_test.dockerfile b/exwayz_test.dockerfile deleted file mode 100644 index 00eff48..0000000 --- a/exwayz_test.dockerfile +++ /dev/null @@ -1,57 +0,0 @@ -# syntax=docker/dockerfile:1.3 -FROM ros:jazzy-ros-core - -# Build argument provided by buildx/BuildKit: `TARGETARCH` (amd64, arm64, etc.). -# Default to amd64 when not provided. -ARG TARGETARCH=amd64 -ARG GRAPICAL_ENV=TRUE - -# Copy both architecture-specific packages into the image and choose the right one at build time -COPY pkgs/exwayz_3d_mapping-1.2.2-linux-u24.04-amd64.deb /tmp/exwayz_amd64.deb -COPY pkgs/exwayz_3d_mapping-1.2.2-linux-u24.04-aarch64.deb /tmp/exwayz_aarch64.deb - -# Install dependencies and setup for GUI applications -ENV DISPLAY=:0 -ENV WAYLAND_DISPLAY=wayland-0 -ENV XDG_SESSION_TYPE=x11 -ENV XDG_RUNTIME_DIR=/mnt/wslg/runtime-dir -#If debug, install the following: -RUN if [ "$GRAPHICAL_ENV" = "TRUE" ]; then \ - apt update && apt install -y libgl1-mesa-dev libosmesa6-dev libglew-dev libgles2-mesa-dev libglfw3-dev libstdc++6 mesa-utils; \ - fi - #TODO we're installing unneccessary things like the humanity-icons package, clean this up later. - - -# RUN --mount=type=secret,id=exwayz_license set -eux; \ -# if [ "${TARGETARCH}" = "aarch64" ]; then \ -# pkg=/tmp/exwayz_aarch64.deb; \ -# else \ -# pkg=/tmp/exwayz_amd64.deb; \ -# fi; \ -# apt-get update; \ -# apt-get install -fy "$pkg"; \ -# if [ -s /run/secrets/exwayz_license ]; then \ -# exwayz_license --query "$(cat /run/secrets/exwayz_license)" || true; \ -# fi; \ -# rm -f /tmp/exwayz_amd64.deb /tmp/exwayz_aarch64.deb; \ -# rm -rf /var/lib/apt/lists/* - -COPY licenses/exwayz_liscence.lic /tmp/exwayz_license -RUN set -eux; \ - apt-get update; \ - apt-get install -fy /tmp/exwayz_amd64.deb; \ - if [ -f /tmp/exwayz_license ]; then \ - exwayz_license --query "$(cat /tmp/exwayz_license)" || true; \ - else \ - echo "No license file provided"; \ - exit 1; \ - fi; \ - rm -f /tmp/exwayz_amd64.deb /tmp/exwayz_aarch64.deb; \ - rm -f /tmp/exwayz_license; \ - rm -rf /var/lib/apt/lists/* - -# # Change the working directory to /app -# WORKDIR /app - -# Set entrypoint -ENTRYPOINT ["/ros_entrypoint.sh"] diff --git a/start_exwayz_mapping_container.sh b/start_exwayz_mapping_container.sh new file mode 100644 index 0000000..661f81b --- /dev/null +++ b/start_exwayz_mapping_container.sh @@ -0,0 +1,157 @@ +#!/bin/bash + +# ============================================================================= +# +# Script to manage and interact with the Exwayz development container. +# +# Author: Gemini +# Reviewer: Gemini (as Senior Developer) +# +# ============================================================================= + +# Exit immediately if a command exits with a non-zero status. +set -e + +# --- Configuration --- +readonly CONTAINER_NAME="ExwayzMapping" +readonly IMAGE_NAME="beckhoff-exwayz:latest" +readonly HOST_DIR="$(pwd)" # Use the current directory from where the script is run +readonly CONTAINER_DIR="/app" +readonly MOUNT_PATH="${HOST_DIR}:${CONTAINER_DIR}" + +# Default network setting. Can be overridden with --network flag. +NETWORK_NAME="host" +WORKING_DIR="${CONTAINER_DIR}" +# --- Helper Functions --- + +# Displays a user-friendly usage message. +usage() { + cat < Specify a network name or 'host'. Defaults to 'host'. + --working-dir Specify the directory inside the container to use as working directory. Defaults to the /app. + --help Shows this usage message. + +Commands: + Creates and starts the container if needed, then attaches an interactive shell. + shell Explicitly creates, starts, and attaches an interactive shell. + stop Stops the running container. + rm Stops and removes the container. + * Executes any other command inside the container (e.g., "$0 ros2 topic list"). + +EOF + exit 1 +} + +# Executes a command inside the running container with the ROS2 environment sourced. +# $@ - The command and its arguments to execute. +exec_in_container() { + echo "--- Executing in container (with ROS2): '$@' ---" + local ros2_setup_command=" + if [ -n \"\$ROS_DISTRO\" ] && [ -f \"/opt/ros/\$ROS_DISTRO/setup.bash\" ]; then + source \"/opt/ros/\$ROS_DISTRO/setup.bash\" --; + echo 'Sourced ROS2 environment.' + else + echo 'Warning: \$ROS_DISTRO not set or setup file not found. Continuing without sourcing ROS2 environment.' >&2 + fi; + exec \"\$@\" + " + podman exec -it -w "${WORKING_DIR}" "${CONTAINER_NAME}" \ + /bin/bash -c "${ros2_setup_command}" bash "$@" +} + + +# --- Argument Parsing --- + +# Parse flags like --network before handling commands. +while [[ $# -gt 0 ]]; do + case "$1" in + --network) + if [[ -z "$2" ]]; then + echo "Error: --network requires a name." >&2 + exit 1 + fi + NETWORK_NAME="$2" + shift # remove --network + shift # remove its value + ;; + --working-dir) + if [[ -z "$2" ]]; then + echo "Error: --working-dir requires a path." >&2 + exit 1 + fi + WORKING_DIR="$2" + shift # remove --working-dir + shift # remove its value + ;; + --help) + usage + ;; + *) + # Not a flag we recognize, so it must be the start of the command. + break + ;; + esac +done + + +# --- Main Logic --- + +# Handle stateless commands that don't require the container to be running. +case "$1" in + stop) + echo "Stopping container '${CONTAINER_NAME}'..." + podman stop "${CONTAINER_NAME}" + exit 0 + ;; + rm) + echo "Stopping and removing container '${CONTAINER_NAME}'..." + # Stop container, ignoring errors if it's already stopped. + podman stop "${CONTAINER_NAME}" >/dev/null 2>&1 || true + podman rm "${CONTAINER_NAME}" + exit 0 + ;; +esac + +# --- Container Lifecycle Management --- +# For all other commands, ensure the container is running. + +# Check if a container with the specified name already exists. +if ! podman ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}"$; then + echo "Container '${CONTAINER_NAME}' not found. Creating and starting a new one..." + podman run -d --name "${CONTAINER_NAME}" \ + --network="${NETWORK_NAME}" \ + --ipc=host \ + --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \ + -v "${MOUNT_PATH}" \ + -w "${CONTAINER_DIR}" \ + "${IMAGE_NAME}" \ + tail -f /dev/null # Keep container running + echo "Container created and started." +# If the container exists, check if it is running. +elif ! podman ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}"$; then + echo "Container '${CONTAINER_NAME}' exists but is stopped. Starting it..." + podman start "${CONTAINER_NAME}" + echo "Container started." +else + echo "Container '${CONTAINER_NAME}' is already running." +fi + + +# --- Command Execution --- + +# Decide what to execute inside the container. +case "$1" in + "" | "shell") # No arguments or "shell" argument + exec_in_container /bin/bash + ;; + *) + exec_in_container "$@" + ;; +esac + +echo "Script finished." \ No newline at end of file