Skip to content

Commit

Permalink
added --ros option to docker scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
dusty-nv committed Jun 15, 2023
1 parent d5a9abd commit 18a368f
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 56 deletions.
6 changes: 3 additions & 3 deletions docker/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,18 @@ if [ -z $BASE_IMAGE ]; then
exit 1
fi
elif [ $ARCH = "x86_64" ]; then
BASE_IMAGE="nvcr.io/nvidia/pytorch:$CONTAINER_VERSION-py3"
BASE_IMAGE="nvcr.io/nvidia/pytorch:$CONTAINER_TAG-py3"
fi
fi

echo "BASE_IMAGE=$BASE_IMAGE"
echo "TAG=$TAG"
echo "CONTAINER_IMAGE=$CONTAINER_LOCAL_IMAGE"

# distro release-dependent build options
source docker/containers/scripts/opencv_version.sh

# build the container
sudo docker build -t $TAG -f Dockerfile \
sudo docker build -t $CONTAINER_LOCAL_IMAGE -f Dockerfile \
--build-arg BASE_IMAGE=$BASE_IMAGE \
--build-arg OPENCV_URL=$OPENCV_URL \
--build-arg OPENCV_DEB=$OPENCV_DEB \
Expand Down
2 changes: 1 addition & 1 deletion docker/push.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ push()
echo "done pushing image $CONTAINER_REMOTE_IMAGE"
}

push $TAG
push $CONTAINER_LOCAL_IMAGE
104 changes: 72 additions & 32 deletions docker/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,38 @@ show_help() {
echo " "
echo " ./docker/run.sh --container DOCKER_IMAGE"
echo " --volume HOST_DIR:MOUNT_DIR"
echo " --ros ROS_DISTRO"
echo " --run RUN_COMMAND"
echo " "
echo "args:"
echo " "
echo " --help Show this help text and quit"
echo " "
echo " -c, --container DOCKER_IMAGE Specifies the name of the Docker container"
echo " image to use (default: 'nvidia-l4t-base')"
echo " image to use (default: 'jetson-inference')"
echo " "
echo " --dev Runs the container in development mode, where the source"
echo " files are mounted into the container dynamically, so they"
echo " can more easily be edited from the host machine."
echo " "
echo " -v, --volume HOST_DIR:MOUNT_DIR Mount a path from the host system into"
echo " the container. Should be specified as:"
echo " "
echo " -v /my/host/path:/my/container/path"
echo " "
echo " (these should be absolute paths)"
echo " These should be absolute paths, and you"
echo " can specify multiple --volume options."
echo " "
echo " --ros DISTRO Specifies the ROS distro to use, one of:"
echo " 'noetic', 'foxy', 'galactic', 'humble', 'iron'"
echo " This will enable the use of ros_deep_learning package."
echo " When run with just --ros flag, the default distro is foxy."
echo " "
echo " -r, --run RUN_COMMAND Command to run once the container is started."
echo " Note that this argument must be invoked last,"
echo " as all further arguments will form the command."
echo " If no run command is specified, an interactive"
echo " terminal into the container will be provided."
echo " "
}

die() {
Expand All @@ -45,9 +55,6 @@ die() {
exit 1
}

# find container tag from L4T version
source docker/tag.sh

# paths to some project directories
NETWORKS_DIR="data/networks"
CLASSIFY_DIR="python/training/classification"
Expand All @@ -57,25 +64,27 @@ RECOGNIZER_DIR="python/www/recognizer"
DOCKER_ROOT="/jetson-inference" # where the project resides inside docker

# generate mount commands
DATA_VOLUME="\
DATA_VOLUME=" \
--volume $PWD/data:$DOCKER_ROOT/data \
--volume $PWD/$CLASSIFY_DIR/data:$DOCKER_ROOT/$CLASSIFY_DIR/data \
--volume $PWD/$CLASSIFY_DIR/models:$DOCKER_ROOT/$CLASSIFY_DIR/models \
--volume $PWD/$DETECTION_DIR/data:$DOCKER_ROOT/$DETECTION_DIR/data \
--volume $PWD/$DETECTION_DIR/models:$DOCKER_ROOT/$DETECTION_DIR/models \
--volume $PWD/$RECOGNIZER_DIR/data:$DOCKER_ROOT/$RECOGNIZER_DIR/data"
--volume $PWD/$RECOGNIZER_DIR/data:$DOCKER_ROOT/$RECOGNIZER_DIR/data "

# parse user arguments
USER_VOLUME=""
USER_COMMAND=""
USER_VOLUME=""
DEV_VOLUME=""
ROS_DISTRO=""

while :; do
case $1 in
-h|-\?|--help)
show_help # Display a usage synopsis.
show_help
exit
;;
-c|--container) # Takes an option argument; ensure it has been specified.
-c|--container) # takes an option argument; ensure it has been specified.
if [ "$2" ]; then
CONTAINER_IMAGE=$2
shift
Expand All @@ -84,25 +93,42 @@ while :; do
fi
;;
--container=?*)
CONTAINER_IMAGE=${1#*=} # Delete everything up to "=" and assign the remainder.
CONTAINER_IMAGE=${1#*=} # delete everything up to "=" and assign the remainder.
;;
--container=) # Handle the case of an empty --image=
--container=) # handle the case of an empty flag
die 'ERROR: "--container" requires a non-empty option argument.'
;;
--dev)
DEV_VOLUME=" --volume $PWD:$DOCKER_ROOT "
;;
-v|--volume)
if [ "$2" ]; then
USER_VOLUME=" -v $2 "
USER_VOLUME="$USER_VOLUME --volume $2 "
shift
else
die 'ERROR: "--volume" requires a non-empty option argument.'
fi
;;
--volume=?*)
USER_VOLUME=" -v ${1#*=} " # Delete everything up to "=" and assign the remainder.
USER_VOLUME="$USER_VOLUME --volume ${1#*=} "
;;
--volume=) # Handle the case of an empty --image=
--volume=)
die 'ERROR: "--volume" requires a non-empty option argument.'
;;
--ros)
if [ "$2" ]; then
ROS_DISTRO=$2
shift
else
ROS_DISTRO="foxy"
fi
;;
--ros=?*)
ROS_DISTRO=${1#*=}
;;
--ros=)
die 'ERROR: "--ros" requires a non-empty option argument.'
;;
-r|--run)
if [ "$2" ]; then
shift
Expand All @@ -111,27 +137,27 @@ while :; do
die 'ERROR: "--run" requires a non-empty option argument.'
fi
;;
--) # End of all options.
--)
shift
break
;;
-?*)
printf 'WARN: Unknown option (ignored): %s\n' "$1" >&2
;;
*) # Default case: No more options, so break out of the loop.
*) # default case: No more options, so break out of the loop.
break
esac

shift
done

echo "CONTAINER: $CONTAINER_IMAGE"
echo "DATA_VOLUME: $DATA_VOLUME"
echo "USER_VOLUME: $USER_VOLUME"
echo "USER_COMMAND: $USER_COMMAND"
# select container tag (unless specified by user)
if [ -z "$CONTAINER_IMAGE" ]; then
source docker/tag.sh
fi

# check for V4L2 devices
V4L2_DEVICES=" "
V4L2_DEVICES=""

for i in {0..9}
do
Expand All @@ -140,34 +166,48 @@ do
fi
done

echo "V4L2_DEVICES: $V4L2_DEVICES"

# check for display
DISPLAY_DEVICE=" "
DISPLAY_DEVICE=""

if [ -n "$DISPLAY" ]; then
sudo xhost +si:localuser:root
DISPLAY_DEVICE="-e DISPLAY=$DISPLAY -v /tmp/.X11-unix/:/tmp/.X11-unix"
DISPLAY_DEVICE=" -e DISPLAY=$DISPLAY -v /tmp/.X11-unix/:/tmp/.X11-unix "
fi

echo "DISPLAY_DEVICE: $DISPLAY_DEVICE"
# print configuration
print_var()
{
if [ -n "${!1}" ]; then # reference var by name - https://stackoverflow.com/a/47768983
local trimmed="$(echo -e "${!1}" | sed -e 's/^[[:space:]]*//')" # remove leading whitespace - https://stackoverflow.com/a/3232433
printf '%-17s %s\n' "$1:" "$trimmed" # justify prefix - https://unix.stackexchange.com/a/354094
fi
}

print_var "CONTAINER_IMAGE"
print_var "ROS_DISTRO"
print_var "DATA_VOLUME"
print_var "DEV_VOLUME"
print_var "USER_VOLUME"
print_var "USER_COMMAND"
print_var "V4L2_DEVICES"
print_var "DISPLAY_DEVICE"

# run the container
if [ $ARCH = "aarch64" ]; then

# /proc or /sys files aren't mountable into docker
cat /proc/device-tree/model > /tmp/nv_jetson_model

sudo docker run --runtime nvidia -it --rm \
--network host \
-v /tmp/argus_socket:/tmp/argus_socket \
-v /etc/enctune.conf:/etc/enctune.conf \
-v /etc/nv_tegra_release:/etc/nv_tegra_release \
-v /tmp/nv_jetson_model:/tmp/nv_jetson_model \
$DISPLAY_DEVICE $V4L2_DEVICES \
$DATA_VOLUME $USER_VOLUME \
$DATA_VOLUME $USER_VOLUME $DEV_VOLUME \
$CONTAINER_IMAGE $USER_COMMAND

elif [ $ARCH = "x86_64" ]; then

sudo docker run --gpus all -it --rm \
Expand All @@ -177,7 +217,7 @@ elif [ $ARCH = "x86_64" ]; then
--ulimit stack=67108864 \
-e NVIDIA_DRIVER_CAPABILITIES=all \
$DISPLAY_DEVICE $V4L2_DEVICES \
$DATA_VOLUME $USER_VOLUME \
$DATA_VOLUME $USER_VOLUME $DEV_VOLUME \
$CONTAINER_IMAGE $USER_COMMAND

fi
Expand Down
42 changes: 22 additions & 20 deletions docker/tag.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,52 @@
source docker/containers/scripts/l4t_version.sh

if [ $ARCH = "aarch64" ]; then
# local container:tag name
CONTAINER_IMAGE="jetson-inference:r$L4T_VERSION"
# local container tag
CONTAINER_TAG="r$L4T_VERSION"

# incompatible L4T version
function version_error()
version_error()
{
echo "cannot find compatible jetson-inference docker container for L4T R$L4T_VERSION"
echo "please upgrade to the latest JetPack, or build jetson-inference natively from source"
echo "Docker containers aren't supported on Jetson prior to JetPack 4.4 / L4T R32.4.3"
echo "Please upgrade to the latest JetPack, or build jetson-inference natively from source"
exit 1
}

# get remote container URL
# adjust tags for compatible L4T versions
if [ $L4T_RELEASE -eq 32 ]; then
if [[ $L4T_REVISION_MAJOR -lt 4 && $L4T_REVISION_MINOR -gt 4 ]]; then
# L4T R32.4 was the first version containers are supported on
version_error
elif [ $L4T_REVISION_MAJOR -eq 5 ]; then
# L4T R32.5.x all run the R32.5.0 container
CONTAINER_IMAGE="jetson-inference:r32.5.0"
CONTAINER_TAG="r32.5.0"
elif [ $L4T_REVISION_MAJOR -eq 7 ]; then
# L4T R32.7.x all run the R32.7.0 container
CONTAINER_IMAGE="jetson-inference:r32.7.1"
CONTAINER_TAG="r32.7.1"
fi
elif [ $L4T_RELEASE -eq 35 ]; then
if [ $L4T_REVISION_MAJOR -gt 3 ]; then
CONTAINER_IMAGE="jetson-inference:r35.3.1"
CONTAINER_TAG="r35.3.1"
fi
fi

CONTAINER_REMOTE_IMAGE="dustynv/$CONTAINER_IMAGE"


elif [ $ARCH = "x86_64" ]; then
# TODO: add logic here for getting the latest release
CONTAINER_VERSION="22.06"
CONTAINER_IMAGE="jetson-inference:$CONTAINER_VERSION"
CONTAINER_REMOTE_IMAGE="dustynv/$CONTAINER_IMAGE"
CONTAINER_TAG="22.06" # NGC pytorch base container tag (TODO: query the latest release)
fi

# TAG is always the local container name
# check if ROS is to be used
if [ -n "$ROS_DISTRO" ]; then
CONTAINER_IMAGE="ros:$ROS_DISTRO-pytorch-l4t-$CONTAINER_TAG"
else
CONTAINER_IMAGE="jetson-inference:$CONTAINER_TAG"
fi

# CONTAINER_LOCAL_IMAGE is always the local container name
# CONTAINER_REMOTE_IMAGE is always the container name in NGC/dockerhub
# CONTAINER_IMAGE is either local container name (if it exists on the system) or the remote image name
TAG=$CONTAINER_IMAGE
CONTAINER_LOCAL_IMAGE="$CONTAINER_IMAGE"
CONTAINER_REMOTE_IMAGE="dustynv/$CONTAINER_LOCAL_IMAGE"

# check for local image
if [[ "$(sudo docker images -q $CONTAINER_IMAGE 2> /dev/null)" == "" ]]; then
if [[ "$(sudo docker images -q $CONTAINER_LOCAL_IMAGE 2> /dev/null)" == "" ]]; then
CONTAINER_IMAGE=$CONTAINER_REMOTE_IMAGE
fi

0 comments on commit 18a368f

Please sign in to comment.