2020-11-08 20:05:38 +00:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
2021-05-01 17:17:32 +00:00
|
|
|
PYODIDE_IMAGE_REPO="pyodide"
|
2022-06-30 04:22:03 +00:00
|
|
|
PYODIDE_IMAGE_TAG="20220629-py310-chrome102-firefox100"
|
2022-08-09 13:36:10 +00:00
|
|
|
PYODIDE_PREBUILT_IMAGE_TAG="0.21.0"
|
2021-05-01 17:17:32 +00:00
|
|
|
DEFAULT_PYODIDE_DOCKER_IMAGE="${PYODIDE_IMAGE_REPO}/pyodide-env:${PYODIDE_IMAGE_TAG}"
|
2021-07-26 22:47:11 +00:00
|
|
|
DEFAULT_PYODIDE_SYSTEM_PORT="none"
|
2021-05-01 17:17:32 +00:00
|
|
|
DOCKER_COMMAND="/bin/bash"
|
2021-06-16 22:04:47 +00:00
|
|
|
DOCKER_INTERACTIVE="--interactive"
|
2021-05-01 17:17:32 +00:00
|
|
|
|
2021-07-05 16:42:38 +00:00
|
|
|
|
|
|
|
USER_HOME="/src/.docker_home"
|
|
|
|
USER_NAME="$(id -u -n)"
|
|
|
|
USER_ID="$(id -u)"
|
2021-07-09 17:41:28 +00:00
|
|
|
USER_GID="$(id -g)"
|
2021-07-05 16:42:38 +00:00
|
|
|
USER_COMMENT_FIELD="${USER_NAME} pyodide user alias"
|
|
|
|
USER_INTERPRETER="/sbin/nologin"
|
2022-03-08 17:29:10 +00:00
|
|
|
USER_FLAG=("--user" "$USER_ID:$USER_GID")
|
2022-03-23 05:43:32 +00:00
|
|
|
HEALTHCHECK_MESSAGE="Done initialization"
|
2021-07-05 16:42:38 +00:00
|
|
|
|
2020-11-08 20:05:38 +00:00
|
|
|
set -eo pipefail
|
|
|
|
|
|
|
|
|
|
|
|
function usage() {
|
|
|
|
cat > /dev/stdout <<EOF
|
2021-04-03 22:20:42 +00:00
|
|
|
Usage: run_docker [OPTIONS] [COMMAND] [ARG...]
|
2020-11-08 20:05:38 +00:00
|
|
|
|
2021-04-03 22:20:42 +00:00
|
|
|
Runs COMMAND in a new Pyodide docker container. If no COMMAND is provided, starts a bash
|
|
|
|
shell in the container.
|
2020-11-08 20:05:38 +00:00
|
|
|
|
2021-04-03 22:20:42 +00:00
|
|
|
Options:
|
|
|
|
-h, --help Show this information and exit.
|
|
|
|
--pre-built Use the prebuilt Pyodide image.
|
|
|
|
This is ignored if the env var PYODIDE_DOCKER_IMAGE is set.
|
|
|
|
-p, --port <port> System port to which to forward.
|
|
|
|
This is ignored if the env var PYODIDE_SYSTEM_PORT is set.
|
|
|
|
If set to 'none', docker instance will not bind to any port.
|
2021-06-16 22:04:47 +00:00
|
|
|
--non-interactive Run docker without the --interactive flag.
|
|
|
|
Useful for running in headless mode on CI server.
|
2021-07-05 16:42:38 +00:00
|
|
|
--root Run as root user inside the container
|
2021-04-03 22:20:42 +00:00
|
|
|
|
|
|
|
Prerequisites:
|
|
|
|
Docker has to be set up on your system.
|
2020-11-08 20:05:38 +00:00
|
|
|
EOF
|
|
|
|
}
|
|
|
|
|
|
|
|
function error() {
|
|
|
|
usage
|
|
|
|
exit 255
|
|
|
|
}
|
|
|
|
|
|
|
|
while [[ $# -gt 0 ]]
|
|
|
|
do
|
|
|
|
key="$1"
|
|
|
|
case $key in
|
|
|
|
-h|--help)
|
|
|
|
usage
|
|
|
|
exit 0
|
|
|
|
;;
|
|
|
|
--pre-built)
|
|
|
|
if [[ -n ${PYODIDE_DOCKER_IMAGE} ]]; then
|
|
|
|
echo "WARNING: will use the env var PYODIDE_DOCKER_IMAGE=${PYODIDE_DOCKER_IMAGE},
|
|
|
|
the flag --pre-built has no effect"
|
|
|
|
fi
|
2021-04-21 19:51:28 +00:00
|
|
|
DEFAULT_PYODIDE_DOCKER_IMAGE="pyodide/pyodide:${PYODIDE_PREBUILT_IMAGE_TAG}"
|
2020-11-08 20:05:38 +00:00
|
|
|
shift
|
|
|
|
;;
|
|
|
|
-p|--port)
|
|
|
|
if [ "$#" -lt 2 ]; then
|
|
|
|
>&2 echo "port cannot be empty"
|
|
|
|
error
|
|
|
|
fi
|
|
|
|
if [[ -n ${PYODIDE_SYSTEM_PORT} ]]; then
|
|
|
|
echo "WARNING: will use the env var PYODIDE_SYSTEM_PORT=${PYODIDE_SYSTEM_PORT} instead of the provided port"
|
2021-08-28 07:03:24 +00:00
|
|
|
else
|
|
|
|
PYODIDE_SYSTEM_PORT=$2
|
2020-11-08 20:05:38 +00:00
|
|
|
fi
|
|
|
|
shift 2
|
|
|
|
;;
|
2021-06-16 22:04:47 +00:00
|
|
|
--non-interactive)
|
|
|
|
DOCKER_INTERACTIVE="--interactive=false"
|
|
|
|
shift
|
|
|
|
;;
|
2021-07-05 16:42:38 +00:00
|
|
|
--root)
|
2022-03-08 17:29:10 +00:00
|
|
|
USER_FLAG=()
|
2021-07-05 16:42:38 +00:00
|
|
|
shift
|
|
|
|
;;
|
2021-04-03 22:20:42 +00:00
|
|
|
-*)
|
2020-11-08 20:05:38 +00:00
|
|
|
>&2 echo "Unknown option $1"
|
|
|
|
error
|
|
|
|
;;
|
2021-04-03 22:20:42 +00:00
|
|
|
*)
|
2022-03-08 05:51:20 +00:00
|
|
|
DOCKER_COMMAND="$*"
|
2021-04-03 22:20:42 +00:00
|
|
|
break
|
|
|
|
;;
|
2020-11-08 20:05:38 +00:00
|
|
|
esac
|
|
|
|
done
|
2018-12-11 07:56:51 +00:00
|
|
|
|
2019-03-21 14:49:50 +00:00
|
|
|
PYODIDE_DOCKER_PORT=${PYODIDE_DOCKER_PORT:-"8000"}
|
2020-11-08 20:05:38 +00:00
|
|
|
PYODIDE_SYSTEM_PORT=${PYODIDE_SYSTEM_PORT:-${DEFAULT_PYODIDE_SYSTEM_PORT}}
|
|
|
|
PYODIDE_DOCKER_IMAGE=${PYODIDE_DOCKER_IMAGE:-${DEFAULT_PYODIDE_DOCKER_IMAGE}}
|
2019-03-21 14:49:50 +00:00
|
|
|
|
2021-04-03 18:38:28 +00:00
|
|
|
# in case the port is not a number, do not bind the port
|
2021-08-28 07:03:24 +00:00
|
|
|
case $PYODIDE_SYSTEM_PORT in
|
2021-04-03 18:38:28 +00:00
|
|
|
none)
|
2022-03-08 17:29:10 +00:00
|
|
|
PORT_CONFIGURATION_LINE=()
|
2021-04-03 18:38:28 +00:00
|
|
|
;;
|
|
|
|
''|*[!0-9]*) # contains a non-digit character, therefore it is not a number
|
2021-08-28 07:03:24 +00:00
|
|
|
echo "WARNING: Invalid port argument '$PYODIDE_SYSTEM_PORT'. Port binding disabled."
|
2022-03-08 17:29:10 +00:00
|
|
|
PORT_CONFIGURATION_LINE=()
|
2021-04-03 18:38:28 +00:00
|
|
|
;;
|
|
|
|
*)
|
2022-03-08 17:29:10 +00:00
|
|
|
PORT_CONFIGURATION_LINE=("-p" "$PYODIDE_SYSTEM_PORT:$PYODIDE_DOCKER_PORT")
|
2021-04-03 18:38:28 +00:00
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
2021-04-04 19:19:54 +00:00
|
|
|
mkdir -p .docker_home
|
|
|
|
|
|
|
|
# Start a detached container as root, add the host uname and uid to /etc/passwd,
|
|
|
|
# then run forever
|
|
|
|
CONTAINER=$(\
|
|
|
|
docker run \
|
2022-03-08 17:29:10 +00:00
|
|
|
"${PORT_CONFIGURATION_LINE[@]}" \
|
2021-04-04 19:19:54 +00:00
|
|
|
-d --rm \
|
2022-03-08 05:51:20 +00:00
|
|
|
-v "$PWD":/src \
|
2021-04-04 19:19:54 +00:00
|
|
|
--user root \
|
2021-03-31 19:53:15 +00:00
|
|
|
--shm-size 2g \
|
2020-11-08 20:05:38 +00:00
|
|
|
"${PYODIDE_DOCKER_IMAGE}" \
|
2021-04-04 19:19:54 +00:00
|
|
|
/bin/bash -c " \
|
2022-06-08 19:24:17 +00:00
|
|
|
groupadd --gid '$USER_GID' '$USER_NAME'; \
|
2022-03-21 01:01:58 +00:00
|
|
|
useradd \
|
2022-06-08 19:24:17 +00:00
|
|
|
--home '$USER_HOME' \
|
2022-03-21 01:01:58 +00:00
|
|
|
--uid '$USER_ID' \
|
|
|
|
--gid '$USER_GID' \
|
|
|
|
--comment '$USER_COMMENT_FIELD' \
|
|
|
|
--shell '$USER_INTERPRETER' \
|
|
|
|
--groups sudo \
|
|
|
|
$USER_NAME \
|
|
|
|
; \
|
|
|
|
echo '%sudo ALL=(ALL:ALL) NOPASSWD:ALL' >> /etc/sudoers ; \
|
2022-03-23 05:43:32 +00:00
|
|
|
echo '$HEALTHCHECK_MESSAGE'; \
|
2021-04-04 19:19:54 +00:00
|
|
|
tail -f /dev/null \
|
|
|
|
" \
|
|
|
|
)
|
|
|
|
|
2022-03-23 05:43:32 +00:00
|
|
|
until docker logs "$CONTAINER" 2>&1 | grep -q "$HEALTHCHECK_MESSAGE"; do
|
|
|
|
echo "Waiting for initialization to finish..."
|
|
|
|
sleep 0.2
|
|
|
|
done
|
|
|
|
|
2021-04-04 19:19:54 +00:00
|
|
|
EXIT_STATUS=0
|
|
|
|
# Execute the provided command as the host user with HOME=/src
|
|
|
|
docker exec \
|
2022-03-08 05:51:20 +00:00
|
|
|
"$DOCKER_INTERACTIVE" --tty \
|
2022-03-08 17:29:10 +00:00
|
|
|
"${USER_FLAG[@]}" \
|
2022-03-08 05:51:20 +00:00
|
|
|
"$CONTAINER" \
|
2021-04-04 19:19:54 +00:00
|
|
|
/bin/bash -c "${DOCKER_COMMAND}" || EXIT_STATUS=$?
|
|
|
|
|
2022-03-08 05:51:20 +00:00
|
|
|
docker kill "$CONTAINER" > /dev/null
|
2021-04-04 19:19:54 +00:00
|
|
|
exit $EXIT_STATUS
|