Skip to content

Commit

Permalink
Consolidate jupyter-python to simplify build process
Browse files Browse the repository at this point in the history
  • Loading branch information
robballantyne committed Apr 8, 2024
1 parent ec5a9b7 commit 9cb152a
Show file tree
Hide file tree
Showing 11 changed files with 499 additions and 2 deletions.
20 changes: 20 additions & 0 deletions build/COPY_ROOT/etc/supervisor/supervisord/conf.d/jupyter.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[program:jupyter]
user=$USER_NAME
environment=PROC_NAME="%(program_name)s",USER=$USER_NAME,HOME=/home/$USER_NAME
command=/opt/ai-dock/bin/supervisor-jupyter.sh
process_name=%(program_name)s
numprocs=1
directory=/home/$USER_NAME
priority=100
autostart=true
startsecs=5
startretries=3
autorestart=unexpected
stopsignal=TERM
stopwaitsecs=10
stopasgroup=true
killasgroup=true
stdout_logfile=/var/log/supervisor/jupyter.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=1
redirect_stderr=true
78 changes: 76 additions & 2 deletions build/COPY_ROOT/opt/ai-dock/bin/build/layer0/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,22 @@

source /opt/ai-dock/etc/environment.sh

kernel_path=/usr/local/share/jupyter/kernels/

build_common_main() {
build_common_install_python
build_common_install_jupyter
build_common_install_ipykernel
}

build_common_do_mamba_install() {
build_common_do_mamba_install_python() {
$MAMBA_CREATE -n "$1" python="$2"
printf "/opt/micromamba/envs/%s/lib\n" "$1" >> /etc/ld.so.conf.d/x86_64-linux-gnu.micromamba.80-python.conf
}

build_common_install_python() {
if [[ $PYTHON_VERSION != "all" ]]; then
build_common_do_mamba_install "${PYTHON_MAMBA_NAME}" "${PYTHON_VERSION}"
build_common_do_mamba_install_python "${PYTHON_MAMBA_NAME}" "${PYTHON_VERSION}"
else
# Multi Python
build_common_do_mamba_install "python_310" "3.10"
Expand All @@ -22,4 +26,74 @@ build_common_install_python() {
fi
}

build_common_install_jupyter() {
$MAMBA_CREATE -n jupyter python=3.10
printf "/opt/micromamba/envs/jupyter/lib\n" >> /etc/ld.so.conf.d/x86_64-linux-gnu.micromamba.90-jupyter.conf
$MAMBA_INSTALL -n jupyter \
jupyter \
jupyterlab \
nodejs=20

ln -s /opt/micromamba/envs/jupyter/lib/libuv* /opt/ai-dock/lib/micromamba/

# This must remain clean. User software should not be in this environment
printf "Removing default ipython kernel...\n"
rm -rf /opt/micromamba/envs/jupyter/share/jupyter/kernels/python3
}

build_common_do_mamba_install_ipykernel() {
$MAMBA_INSTALL -n "$1" \
ipykernel \
ipywidgets
}

build_common_do_kernel_install() {
if [[ -n $4 ]]; then
# Add a clone, probably the often-present Python3 (ipykernel) pointed to our default python install
dir="${kernel_path}${3}/"
file="${dir}kernel.json"
cp -rf ${kernel_path}../_template ${dir}

sed -i 's/DISPLAY_NAME/'"$4"'/g' ${file}
sed -i 's/PYTHON_MAMBA_NAME/'"$1"'/g' ${file}
fi
dir="${kernel_path}$1/"
file="${dir}kernel.json"
cp -rf ${kernel_path}../_template ${dir}

sed -i 's/DISPLAY_NAME/'"Python $2"'/g' ${file}
sed -i 's/PYTHON_MAMBA_NAME/'"$1"'/g' ${file}
}

build_common_install_ipykernel() {
if [[ $PYTHON_VERSION != "all" ]]; then
major=${PYTHON_VERSION:0:1}
build_common_do_mamba_install_ipykernel "${PYTHON_MAMBA_NAME}"
build_common_do_kernel_install "${PYTHON_MAMBA_NAME}" "${PYTHON_VERSION}" "python${major}" "Python${major} (ipykernel)"
else
# Multi Python - Use $PYTHON_MAMBA_NAME as default kernel

build_common_do_mamba_install_ipykernel "python_310"
if [[ $PYTHON_MAMBA_NAME = "python_310" ]]; then
build_common_do_kernel_install "python_310" "3.10" "python3" "Python3 (ipykernel)"
else
build_common_do_kernel_install "python_310" "3.10"
fi

build_common_do_mamba_install_ipykernel "python_311"
if [[ $PYTHON_MAMBA_NAME = "python_311" ]]; then
build_common_do_kernel_install "python_311" "3.11" "python3" "Python3 (ipykernel)"
else
build_common_do_kernel_install "python_311" "3.11"
fi

build_common_do_mamba_install_ipykernel "python_312"
if [[ $PYTHON_MAMBA_NAME = "python_312" ]]; then
build_common_do_kernel_install "python_312" "3.12" "python3" "Python3 (ipykernel)"
else
build_common_do_kernel_install "python_312" "3.12"
fi
fi
}

build_common_main "$@"
4 changes: 4 additions & 0 deletions build/COPY_ROOT/opt/ai-dock/bin/jupyter-bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

# Some very hacky nonsense to make jupyter source the .bashrc. FIXME
bash
10 changes: 10 additions & 0 deletions build/COPY_ROOT/opt/ai-dock/bin/jupyter-start-service.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash

if [[ -f /run/container_config || -f /run/workspace_sync ]]; then
printf "** The container is still being prepared **\n\n"
printf "Your service will start automatically - Check the logs for progress (logtail.sh)\n\n"
elif [[ -z $1 ]]; then
printf "Please specify a service to start\n\n"
else
supervisorctl start $1
fi
101 changes: 101 additions & 0 deletions build/COPY_ROOT/opt/ai-dock/bin/supervisor-jupyter.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/bin/bash

trap cleanup EXIT

function cleanup() {
kill $(jobs -p) > /dev/null 2>&1
fuser -k -SIGTERM ${LISTEN_PORT}/tcp > /dev/null 2>&1 &
rm /run/http_ports/$PROXY_PORT > /dev/null 2>&1
}

function start() {
source /opt/ai-dock/etc/environment.sh

LISTEN_PORT=18888
METRICS_PORT=${JUPYTER_METRICS_PORT:-28888}
PROXY_SECURE=true
SERVICE_URL="${JUPYTER_URL:-}"
QUICKTUNNELS=true

if [[ ! -v JUPYTER_PORT || -z $JUPYTER_PORT ]]; then
JUPYTER_PORT=${JUPYTER_PORT_HOST:-8888}
fi
PROXY_PORT=$JUPYTER_PORT

if [[ ! -v JUPYTER_MODE || -z $JUPYTER_MODE ]]; then
JUPYTER_MODE="notebook"
fi
if [[ $JUPYTER_MODE != "notebook" ]]; then
JUPYTER_MODE="lab"
fi

SERVICE_NAME="Jupyter ${JUPYTER_MODE^}"

if [[ ${SERVERLESS,,} = "true" ]]; then
printf "Refusing to start $SERVICE_NAME service in serverless mode\n"
exec sleep 10
fi

file_content="$(
jq --null-input \
--arg listen_port "${LISTEN_PORT}" \
--arg metrics_port "${METRICS_PORT}" \
--arg proxy_port "${PROXY_PORT}" \
--arg proxy_secure "${PROXY_SECURE,,}" \
--arg service_name "${SERVICE_NAME}" \
--arg service_url "${SERVICE_URL}" \
'$ARGS.named'
)"

printf "%s" "$file_content" > /run/http_ports/$PROXY_PORT

# Delay launch until micromamba is ready
if [[ -f /run/workspace_sync ]]; then
printf "Waiting for workspace sync...\n"
/usr/bin/python3 /opt/ai-dock/fastapi/logviewer/main.py \
-p $LISTEN_PORT \
-r 3 \
-s "${SERVICE_NAME}" \
-t "Preparing ${SERVICE_NAME}" &
fastapi_pid=$!

while [[ -f /run/workspace_sync ]]; do
sleep 1
done

kill $fastapi_pid &
wait -n
fi

fuser -k -SIGKILL ${LISTEN_PORT}/tcp > /dev/null 2>&1 &
wait -n

# Allows running in user context when the home directory has non-standard permissions
if [[ $WORKSPACE_MOUNTED == "true" && $WORKSPACE_PERMISSIONS == "false" ]]; then
export JUPYTER_ALLOW_INSECURE_WRITES=true
fi

printf "\nStarting %s...\n" "${SERVICE_NAME:-service}"

# Terminado shell_command needs fixing.
# Bash alone invokes neither profile or bashrc.
micromamba run -n jupyter jupyter \
$JUPYTER_MODE \
--allow-root \
--ip=127.0.0.1 \
--port=$LISTEN_PORT \
--no-browser \
--ServerApp.token='' \
--ServerApp.password='' \
--ServerApp.trust_xheaders=True \
--ServerApp.disable_check_xsrf=False \
--ServerApp.allow_remote_access=True \
--ServerApp.allow_origin='*' \
--ServerApp.allow_credentials=True \
--ServerApp.root_dir=/ \
--ServerApp.preferred_dir="$WORKSPACE" \
--ServerApp.terminado_settings="{'shell_command': ['bash','-c','bash']}" \
--KernelSpecManager.ensure_native_kernel=False
}

start 2>&1
18 changes: 18 additions & 0 deletions build/COPY_ROOT/usr/local/share/jupyter/_template/kernel.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"argv": [
"micromamba",
"run",
"-n",
"PYTHON_MAMBA_NAME",
"python",
"-m",
"ipykernel_launcher",
"-f",
"{connection_file}"
],
"display_name": "DISPLAY_NAME",
"language": "python",
"metadata": {
"debugger": true
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 9cb152a

Please sign in to comment.