Skip to content
Draft
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
126 changes: 96 additions & 30 deletions flow/util/docker_shell
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
#!/usr/bin/env bash

set -ex

# docker_shell — unified launcher for AutoTuner / OpenROAD
#
# Usage: etc/docker_shell [OPTIONS] [-- CMD [ARGS...]]
#
# Options:
# -i, --image IMAGE Docker image (overrides $OR_IMAGE and default)
# --user Map host UID/GID into the container via entrypoint.sh
# --orfs-flow Mount pwd to /OpenROAD-flow-scripts/flow instead of /work
# -p, --port SPEC Forward a port, e.g. --port 8265:8265 (repeatable)
# --dry-run Print the docker command without executing it
# -h|--help Show this help and exit

#
# Method to use docker CLI to determine if we're using docker or podman
#
Expand All @@ -20,7 +31,35 @@ get_container_engine () {
fi
}

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
DEFAULT_IMAGE="openroad/orfs:latest"
MOUNT_TARGET="/work"
USE_USER=false
DRY_RUN=false
PORTS=()
IMAGE=""
CMD_ARGS=()

usage() {
grep '^#' "$0" | sed 's/^# \{0,1\}//'
exit 0
}

while [[ $# -gt 0 ]]; do
case "$1" in
-i|--image) IMAGE="$2"; shift 2 ;;
--user) USE_USER=true; shift ;;
--orfs-flow) MOUNT_TARGET="/OpenROAD-flow-scripts/flow"; shift ;;
-p|--port) PORTS+=("$2"); shift 2 ;;
--dry-run) DRY_RUN=true; shift ;;
-h|--help) usage ;;
--) shift; CMD_ARGS=("$@"); break ;;
-*) echo "Unknown option: $1" >&2; exit 1 ;;
*) CMD_ARGS=("$@"); break ;;
esac
done

# Image resolution: --image > $OR_IMAGE > default
IMAGE="${IMAGE:-${OR_IMAGE:-$DEFAULT_IMAGE}}"

get_container_engine

Expand All @@ -31,41 +70,68 @@ KLAYOUT_CMD=${KLAYOUT_CMD:-/usr/bin/klayout}

XSOCK=/tmp/.X11-unix
XAUTH=/tmp/.docker.xauth
xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
ARGUMENTS=$@
if ! $DRY_RUN; then
xauth nlist ${DISPLAY:-:0} | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
fi

if test -t 0; then
DOCKER_INTERACTIVE=-ti
else
DOCKER_INTERACTIVE=
fi

if [[ $container_engine == "podman" ]]; then
if $USE_USER; then
user_args="--entrypoint=entrypoint.sh --user=root"
user_env="-e CUSTOM_USER=$(id --user --name) -e CUSTOM_USER_ID=$(id --user) -e CUSTOM_GROUP_ID=$(id --group)"
elif [[ $container_engine == "podman" ]]; then
user_args="--privileged --userns=keep-id"
user_env=
else
user_args="-u $(id -u ${USER}):$(id -g ${USER})"
user_env=
fi

PORT_ARGS=()
for port in "${PORTS[@]}"; do
PORT_ARGS+=(-p "$port")
done

CMD_STR=
[[ ${#CMD_ARGS[@]} -gt 0 ]] && CMD_STR="${CMD_ARGS[*]}"

# Source env.sh only when mounting to ORFS flow dir (adds OR tools to PATH).
# AutoTuner images install binaries in /usr/local/bin so env.sh is not needed
# and would error out if absent.
ENV_SH_CMD=
[[ "$MOUNT_TARGET" == "/OpenROAD-flow-scripts/flow" ]] && ENV_SH_CMD=". ../env.sh;"

# Build the command once; dry-run prints it, otherwise exec it.
DOCKER_CMD=(
"$container_engine" run --rm -i
$DOCKER_INTERACTIVE
$user_env $user_args
-e LIBGL_ALWAYS_SOFTWARE=1
-e QT_X11_NO_MITSHM=1
-e XDG_RUNTIME_DIR=/tmp/xdg-run
-e "DISPLAY=${DISPLAY:-:0}"
-e QT_XKB_CONFIG_ROOT=/usr/share/X11/xkb
-v "$XSOCK:$XSOCK"
-v "$XAUTH:$XAUTH"
-e "XAUTHORITY=$XAUTH"
-e FLOW_HOME=/OpenROAD-flow-scripts/flow/
-e "YOSYS_EXE=$YOSYS_EXE"
-e "OPENROAD_EXE=$OPENROAD_EXE"
-e "KLAYOUT_CMD=$KLAYOUT_CMD"
-v "$WORKSPACE:${MOUNT_TARGET}"
--network host
"${PORT_ARGS[@]}"
"$IMAGE"
bash -c "set -ex; mkdir /tmp/xdg-run; cd ${MOUNT_TARGET}; ${ENV_SH_CMD}$CMD_STR"
)

if $DRY_RUN; then
echo "${DOCKER_CMD[*]}"
exit 0
fi

# Most of these options below has to do with allowing to
# run the OpenROAD GUI from within Docker.
docker run $user_args \
-e LIBGL_ALWAYS_SOFTWARE=1 \
-e "QT_X11_NO_MITSHM=1" \
-e XDG_RUNTIME_DIR=/tmp/xdg-run \
-e DISPLAY=$DISPLAY \
-e QT_XKB_CONFIG_ROOT=/usr/share/X11/xkb \
-v $XSOCK:$XSOCK \
-v $XAUTH:$XAUTH \
-e XAUTHORITY=$XAUTH \
-e FLOW_HOME=/OpenROAD-flow-scripts/flow/ \
-e YOSYS_EXE=$YOSYS_EXE \
-e OPENROAD_EXE=$OPENROAD_EXE \
-e KLAYOUT_CMD=$KLAYOUT_CMD \
-v $WORKSPACE:/OpenROAD-flow-scripts/flow:Z \
--network host \
$DOCKER_INTERACTIVE \
${OR_IMAGE:-openroad/orfs:latest} \
bash -c "set -ex
mkdir /tmp/xdg-run
cd /OpenROAD-flow-scripts/flow
. ../env.sh
$ARGUMENTS
"
exec "${DOCKER_CMD[@]}"