Files
WAR_exwayz3dm/start_exwayz_mapping_container.sh

157 lines
4.9 KiB
Bash

#!/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="exwayzMapping: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 <<EOF
Usage: $0 [options] [command] [args...]
Manages the Exwayz container lifecycle and provides an execution environment.
Options:
--network <name> Specify a network name or 'host'. Defaults to 'host'.
--working-dir <path> Specify the directory inside the container to use as working directory. Defaults to the /app.
--help Shows this usage message.
Commands:
<none> 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."