Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable composite compose #455

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 85 additions & 25 deletions docker/container.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,24 @@ fi

# print the usage description
print_help () {
echo -e "\nusage: $(basename "$0") [-h] [run] [start] [stop] -- Utility for handling docker in Isaac Lab."
echo -e "\noptional arguments:"
echo -e "\t-h, --help Display the help content."
echo -e "\tstart [profile] Build the docker image and create the container in detached mode."
echo -e "\tenter [profile] Begin a new bash process within an existing Isaac Lab container."
echo -e "\tcopy [profile] Copy build and logs artifacts from the container to the host machine."
echo -e "\tstop [profile] Stop the docker container and remove it."
echo -e "\tpush [profile] Push the docker image to the cluster."
echo -e "\tjob [profile] [job_args] Submit a job to the cluster."
echo -e "\n"
echo -e "[profile] is the optional container profile specification and [job_args] optional arguments specific"
echo -e "to the executed script"
echo -e "\nusage: $(basename "$0") [-h] [mode] [options] -- Utility for handling docker in Isaac Lab."
echo -e "\nmode:"
echo -e "\t-h, --help Display the help content."
echo -e "\tstart [profile] [options] Build the docker image and create the container in detached mode."
echo -e "\tenter [profile] Begin a new bash process within an existing Isaac Lab container."
echo -e "\tcopy [profile] Copy build and logs artifacts from the container to the host machine."
echo -e "\tstop [profile] [options] Stop the docker container and remove it."
echo -e "\tpush [profile] Push the docker image to the cluster."
echo -e "\tjob [profile] [job_args] Submit a job to the cluster."
echo -e "\tconfig [profile] [options] Parse, resolve and render compose file in canonical format."
echo -e "\nmode arguments:"
echo -e "\t[profile] is the optional container profile specification."
echo -e "\t[job_args] are optional arguments specific to the executed script."
echo -e "\noptions:"
echo -e "\t[-ay, --add_yaml] allows additional .yaml files to be passed to the docker compose command. .yamls will "
echo -e "\t be merged with docker-compose.yaml in the order in which they are provided."
echo -e "\t[-ae, --add_env] allows additional .env files to be passed to the docker compose command. .env will be"
echo -e "\t merged with .env.base in the order in which they are provided."
echo -e "\n" >&2
}

Expand Down Expand Up @@ -112,8 +118,8 @@ resolve_image_extension() {
# check if a .env.$container_profile file exists
# if the argument is necessary a profile, then the file must exists otherwise an info is printed
if [ "$necessary_profile" = true ] && [ ! -f $SCRIPT_DIR/.env.$container_profile ]; then
echo "[Error] The profile '$container_profile' has no .env.$container_profile file!" >&2;
exit 1
echo "[WARN] The profile '$container_profile' has no .env.$container_profile file!" >&2;
echo "[INFO] .env.$container_profile should be added through --add_envs" >&2;
elif [ ! -f $SCRIPT_DIR/.env.$container_profile ]; then
echo "[INFO] No .env.$container_profile found, assume second argument is no profile! Will use default container!" >&2;
container_profile="base"
Expand All @@ -130,7 +136,11 @@ resolve_image_extension() {
if [ "$container_profile" != "base" ]; then
# We have to load multiple .env files here in order to combine
# them for the args from base required for extensions, (i.e. DOCKER_USER_HOME)
add_envs="$add_envs --env-file .env.$container_profile"
env_file=".env.$container_profile"
# Check if the file exists
if [ -f "$SCRIPT_DIR/$env_file" ]; then
add_envs="$add_envs --env-file $env_file"
fi
fi
}

Expand Down Expand Up @@ -230,6 +240,44 @@ x11_cleanup() {
fi
}

parse_key_equal_to_value() {
local value="${1#*=}"
if [ ${value} == ${1} ]; then
value=""
fi
echo ${value}
}

process_mode_args() {
while [ $# -gt 0 ]; do
case $1 in
-ay*|--add_yaml*)
local value=$(parse_key_equal_to_value ${1})
shift
if [ -z ${value} ]; then
value=${1}
shift
fi
add_yamls="$add_yamls --file ${value}"
;;
-ae*|--add_env*)
local value=$(parse_key_equal_to_value ${1})
shift
if [ -z ${value} ]; then
value=${1}
shift
fi
add_envs="$add_envs --env-file ${value}"
;;
*)
echo "Unknown argument: $1"
print_help
exit 1
;;
esac
done
}

#==
# Main
#==
Expand Down Expand Up @@ -257,12 +305,16 @@ profile_arg="$2" # Capture the second argument as the potential profile argument

# Check mode argument and resolve the container profile
case $mode in
build|start|enter|copy|stop|push)
build|start|enter|copy|stop|push|config)
resolve_image_extension "$profile_arg" true
;;
job)
resolve_image_extension "$profile_arg" false
;;
-h)
print_help
exit 0
;;
*)
# Not recognized mode
echo "[Error] Invalid command provided: $mode"
Expand All @@ -277,15 +329,16 @@ echo "[INFO] Using container profile: $container_profile"
# resolve mode
case $mode in
start)
process_mode_args "${@:3}"
echo "[INFO] Building the docker image and starting the container isaac-lab-$container_profile in the background..."
pushd ${SCRIPT_DIR} > /dev/null 2>&1
# Determine if we want x11 forwarding enabled
x11_check
# We have to build the base image as a separate step,
# in case we are building a profile which depends
# upon
docker compose --file docker-compose.yaml --env-file .env.base build isaac-lab-base
docker compose $add_yamls $add_profiles $add_envs up --detach --build --remove-orphans
docker compose $add_yamls $add_envs build isaac-lab-base
docker compose $add_yamls $add_envs $add_profiles up --detach --build --remove-orphans
popd > /dev/null 2>&1
;;
enter)
Expand All @@ -299,10 +352,11 @@ case $mode in
copy)
# Check that desired container is running, exit if it isn't
is_container_running isaac-lab-$container_profile
DOCKER_ISAACLAB_PATH=$(docker exec isaac-lab-$container_profile printenv DOCKER_ISAACLAB_PATH)
echo "[INFO] Copying artifacts from the 'isaac-lab-$container_profile' container..."
echo -e "\t - /workspace/isaaclab/logs -> ${SCRIPT_DIR}/artifacts/logs"
echo -e "\t - /workspace/isaaclab/docs/_build -> ${SCRIPT_DIR}/artifacts/docs/_build"
echo -e "\t - /workspace/isaaclab/data_storage -> ${SCRIPT_DIR}/artifacts/data_storage"
echo -e "\t - ${DOCKER_ISAACLAB_PATH}/logs -> ${SCRIPT_DIR}/artifacts/logs"
echo -e "\t - ${DOCKER_ISAACLAB_PATH}/docs/_build -> ${SCRIPT_DIR}/artifacts/docs/_build"
echo -e "\t - ${DOCKER_ISAACLAB_PATH}/data_storage -> ${SCRIPT_DIR}/artifacts/data_storage"
# enter the script directory
pushd ${SCRIPT_DIR} > /dev/null 2>&1
# We have to remove before copying because repeated copying without deletion
Expand All @@ -315,18 +369,19 @@ case $mode in
mkdir -p ./artifacts/docs

# copy the artifacts
docker cp isaac-lab-$container_profile:/workspace/isaaclab/logs ./artifacts/logs
docker cp isaac-lab-$container_profile:/workspace/isaaclab/docs/_build ./artifacts/docs/_build
docker cp isaac-lab-$container_profile:/workspace/isaaclab/data_storage ./artifacts/data_storage
docker cp isaac-lab-$container_profile:${DOCKER_ISAACLAB_PATH}/logs ./artifacts/logs
docker cp isaac-lab-$container_profile:${DOCKER_ISAACLAB_PATH}/docs/_build ./artifacts/docs/_build
docker cp isaac-lab-$container_profile:${DOCKER_ISAACLAB_PATH}/data_storage ./artifacts/data_storage
echo -e "\n[INFO] Finished copying the artifacts from the container."
popd > /dev/null 2>&1
;;
stop)
process_mode_args "${@:3}"
# Check that desired container is running, exit if it isn't
is_container_running isaac-lab-$container_profile
echo "[INFO] Stopping the launched docker container isaac-lab-$container_profile..."
pushd ${SCRIPT_DIR} > /dev/null 2>&1
docker compose --file docker-compose.yaml $add_profiles $add_envs down
docker compose $add_yamls $add_envs $add_profiles down
x11_cleanup
popd > /dev/null 2>&1
;;
Expand Down Expand Up @@ -378,6 +433,11 @@ case $mode in
ssh $CLUSTER_LOGIN "cd $CLUSTER_ISAACLAB_DIR && sbatch $CLUSTER_ISAACLAB_DIR/docker/cluster/submit_job.sh" "$CLUSTER_ISAACLAB_DIR" "isaac-lab-$container_profile" "${@:2}"
fi
;;
config)
process_mode_args "${@:3}"
pushd ${SCRIPT_DIR} > /dev/null 2>&1
docker compose $add_yamls $add_envs $add_profiles config
;;
*)
# Not recognized mode
echo "[Error] Invalid command provided: $mode"
Expand Down
10 changes: 5 additions & 5 deletions docker/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,24 +36,24 @@ x-default-isaac-lab-volumes: &default-isaac-lab-volumes
# be reflected within the container immediately
- type: bind
source: ../source
target: /workspace/isaaclab/source
target: ${DOCKER_ISAACLAB_PATH}/source
- type: bind
source: ../docs
target: /workspace/isaaclab/docs
target: ${DOCKER_ISAACLAB_PATH}/docs
# The effect of these volumes is twofold:
# 1. Prevent root-owned files from flooding the _build and logs dir
# on the host machine
# 2. Preserve the artifacts in persistent volumes for later copying
# to the host machine
- type: volume
source: isaac-lab-docs
target: /workspace/isaaclab/docs/_build
target: ${DOCKER_ISAACLAB_PATH}/docs/_build
- type: volume
source: isaac-lab-logs
target: /workspace/isaaclab/logs
target: ${DOCKER_ISAACLAB_PATH}/logs
- type: volume
source: isaac-lab-data
target: /workspace/isaaclab/data_storage
target: ${DOCKER_ISAACLAB_PATH}/data_storage

x-default-isaac-lab-environment: &default-isaac-lab-environment
- ISAACSIM_PATH=${DOCKER_ISAACLAB_PATH}/_isaac_sim
Expand Down