mosaic-zero / mosaic
copilot-swe-agent[bot]
Add user ID and group ID to Docker commands for correct file ownership
1e5576e
#!/bin/bash
# Mosaic CLI wrapper script for Docker
# This script enables seamless usage of the Mosaic CLI through Docker
#
# Usage: ./mosaic [mosaic-arguments]
#
# Examples:
# ./mosaic --help
# ./mosaic --slide-path /path/to/slide.svs --output-dir /path/to/output
# ./mosaic --slide-csv /path/to/slides.csv --output-dir /path/to/output
#
# Requirements:
# - Docker installed and running
# - NVIDIA Docker runtime (for GPU support)
# - HF_TOKEN environment variable set
# - Docker image pulled: docker pull tomp/mosaic-gradio
#
# Note: When using --slide-csv, the CSV file and all referenced slides should be
# in the same directory tree. Slides can be in subdirectories relative to
# the CSV file location.
DOCKER_IMAGE="tomp/mosaic-gradio"
USE_GPU=true
die () { echo "FATAL: $*" >&2; exit 1; }
# Check if Docker is available
command -v docker >/dev/null 2>&1 || die "Docker is not installed or not in PATH"
# Check if HF_TOKEN is set
[[ -n $HF_TOKEN ]] || die "HF_TOKEN environment variable is not set. Please set it to your HuggingFace access token."
# Check if nvidia runtime is available
if docker info 2>/dev/null | grep -q nvidia; then
USE_GPU=true
else
echo "Warning: NVIDIA Docker runtime not detected. Running without GPU support." >&2
echo " To enable GPU support, install the NVIDIA Container Toolkit." >&2
USE_GPU=false
fi
# Parse arguments to identify paths that need to be mounted
VOLUME_MOUNTS=()
ARGS=()
while [[ $# -gt 0 ]]; do
ARG="$1"
case "$ARG" in
--slide-path)
shift
SLIDE_PATH="$1"
if [[ -n "$SLIDE_PATH" ]]; then
# Convert to absolute path
SLIDE_PATH=$(readlink -f "$SLIDE_PATH")
SLIDE_DIR=$(dirname "$SLIDE_PATH")
SLIDE_FILE=$(basename "$SLIDE_PATH")
# Mount the directory containing the slide
VOLUME_MOUNTS+=("-v" "$SLIDE_DIR:/mnt/slides:ro")
# Pass the container path to mosaic
ARGS+=("--slide-path" "/mnt/slides/$SLIDE_FILE")
fi
shift
;;
--slide-csv)
shift
CSV_PATH="$1"
if [[ -n "$CSV_PATH" ]]; then
# Convert to absolute path
CSV_PATH=$(readlink -f "$CSV_PATH")
CSV_DIR=$(dirname "$CSV_PATH")
CSV_FILE=$(basename "$CSV_PATH")
# Mount the parent directory of CSV (to allow slides in subdirs)
# This allows the CSV to reference slides with relative paths
VOLUME_MOUNTS+=("-v" "$CSV_DIR:/mnt/data:ro")
# Pass the container path to mosaic
ARGS+=("--slide-csv" "/mnt/data/$CSV_FILE")
fi
shift
;;
--output-dir)
shift
OUTPUT_DIR="$1"
if [[ -n "$OUTPUT_DIR" ]]; then
# Convert to absolute path and create if it doesn't exist
mkdir -p "$OUTPUT_DIR"
OUTPUT_DIR=$(readlink -f "$OUTPUT_DIR")
# Mount the output directory
VOLUME_MOUNTS+=("-v" "$OUTPUT_DIR:/mnt/output")
# Pass the container path to mosaic
ARGS+=("--output-dir" "/mnt/output")
fi
shift
;;
*)
# Pass through all other arguments
ARGS+=("$ARG")
shift
;;
esac
done
# Remove duplicate volume mounts
UNIQUE_MOUNTS=$(printf '%s\n' "${VOLUME_MOUNTS[@]}" | awk '!seen[$0]++')
VOLUME_ARGS=()
while IFS= read -r mount; do
[[ -n "$mount" ]] && VOLUME_ARGS+=("$mount")
done <<< "$UNIQUE_MOUNTS"
# Run the Docker container with the mosaic CLI
# Override the entrypoint to run mosaic command instead of gradio_app
GPU_ARGS=()
if [ "$USE_GPU" = true ]; then
GPU_ARGS+=("--gpus=all" "--runtime=nvidia")
fi
# Get current user ID and group ID to ensure output files have correct ownership
USER_ID=$(id -u)
GROUP_ID=$(id -g)
docker run --rm \
"${GPU_ARGS[@]}" \
--user "${USER_ID}:${GROUP_ID}" \
--env HF_TOKEN="${HF_TOKEN}" \
--shm-size=500m \
"${VOLUME_ARGS[@]}" \
--entrypoint mosaic \
"$DOCKER_IMAGE" \
"${ARGS[@]}"