diff --git a/src/jupyter-aou/docker-compose.yaml b/src/jupyter-aou/docker-compose.yaml index b21fa634..74d2c5c2 100644 --- a/src/jupyter-aou/docker-compose.yaml +++ b/src/jupyter-aou/docker-compose.yaml @@ -1,4 +1,4 @@ -version: "2.4" +version: '2.4' services: app: container_name: "application-server" @@ -7,18 +7,16 @@ services: restart: always volumes: - .:/workspace:cached + - ./wb:/usr/bin/wb:ro + - /tmp/wb-mount:/home/jupyter/workspace:slave + - ssh-keys:/ssh-keys ports: - - "8888:8888" + - '8888:8888' networks: - app-network - cap_add: - - SYS_ADMIN - devices: - - /dev/fuse - security_opt: - - apparmor:unconfined depends_on: - wondershaper + - wbcli wondershaper: container_name: "wondershaper" image: "us-west2-docker.pkg.dev/shared-pub-buckets-94mvrf/workbench-artifacts/app-wondershaper@sha256:dd9df1811b9d15f4f8d95b6e515a2371e12d238240b8ef7359be77d961e79e3a" @@ -26,6 +24,28 @@ services: network_mode: "host" cap_add: - NET_ADMIN + wbcli: + container_name: "wbcli" + image: "wbcli:local" + restart: always + working_dir: /workspace + volumes: + - .:/workspace:cached + - ssh-keys:/ssh-keys + - /tmp/wb-mount:/home/wbcli/workspace:shared + networks: + - app-network + cap_add: + - SYS_ADMIN + devices: + - /dev/fuse + security_opt: + - apparmor:unconfined + environment: + CLOUD: ${templateOption:cloud} + LOG_IN: ${templateOption:login} networks: app-network: external: true +volumes: + ssh-keys: diff --git a/src/jupyter-aou/wb b/src/jupyter-aou/wb new file mode 100644 index 00000000..82fb3bb5 --- /dev/null +++ b/src/jupyter-aou/wb @@ -0,0 +1,2 @@ +#!/bin/sh +/usr/bin/ssh -i /ssh-keys/wb-key -T -o "StrictHostKeyChecking no" wbcli@wbcli $@ diff --git a/src/jupyter-aou/wbcli/Dockerfile b/src/jupyter-aou/wbcli/Dockerfile new file mode 100644 index 00000000..0b5c6bbe --- /dev/null +++ b/src/jupyter-aou/wbcli/Dockerfile @@ -0,0 +1,50 @@ +FROM debian:latest + +RUN apt-get update --yes && \ + apt-get install -yq --no-install-recommends \ + jq \ + openssh-server \ + sudo \ + curl \ + lsb-release \ + locales \ + # gcloud CLI dependencies + apt-transport-https \ + ca-certificates \ + gnupg \ + fuse \ + # aws CLI dependencies + libc6 \ + groff \ + # Install Java 17 and jq for Workbench CLI + openjdk-17-jdk + +# Install gcloud CLI and gcsfuse +RUN echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" > /etc/apt/sources.list.d/google-cloud-sdk.list && \ + echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt gcsfuse-$(lsb_release -c -s) main" > /etc/apt/sources.list.d/gcsfuse.list && \ + curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg && \ + apt-get update -y && \ + apt-get install -yq --no-install-recommends google-cloud-cli gcsfuse + +# Install aws CLI and goofys for s3 bucket mounting +RUN apt-get update -y && \ + apt-get install -yq --no-install-recommends awscli && \ + curl -L "https://github.com/kahing/goofys/releases/latest/download/goofys" -o goofys && \ + chmod +x goofys && \ + mv goofys /usr/local/bin/ + +COPY wb /wb +RUN chmod +x /wb +COPY entrypoint.sh /entrypoint.sh + +ENV USER=wbcli +ENV UID=1001 +ENV USER_HOME_DIR=/home/wbcli + +# Create a user with the shell set to /wb. This prevents the user from executing +# any other commands +RUN useradd -l -m -d $USER_HOME_DIR \ + -u $UID \ + -s /wb $USER + +ENTRYPOINT [ "/bin/sh", "/entrypoint.sh" ] diff --git a/src/jupyter-aou/wbcli/entrypoint.sh b/src/jupyter-aou/wbcli/entrypoint.sh new file mode 100644 index 00000000..699d7c22 --- /dev/null +++ b/src/jupyter-aou/wbcli/entrypoint.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +cleanup() { + wb resource unmount + exit +} +trap cleanup INT TERM + +# SSH Key setup +mkdir -p /home/wbcli/.ssh +cd /home/wbcli/.ssh + +# Generate a new ssh key and add it to authorized_keys +ssh-keygen -q -f ./wb-key -N "" +(echo -n 'restrict '; cat ./wb-key.pub) >> ./authorized_keys +chmod 600 ./authorized_keys +chown -R wbcli:wbcli /home/wbcli/.ssh +service ssh start + +# SSH permission checking is only run when ssh is run by the owner of the key +# file. Set the owner to nobody, but allow universal read access +mv ./wb-key /ssh-keys/wb-key +chmod 644 /ssh-keys/wb-key +chown nobody /ssh-keys/wb-key + +chmod a+w /home/wbcli/workspace + +# Install CLI and mount resources +# TODO takes too long to set up, set up in docker container +/workspace/startupscript/post-startup.sh wbcli /home/wbcli $CLOUD $LOG_IN + +touch /ready + +# Keep the container running, but in the background so that interrupts can be +# caught +tail -f /dev/null & +wait $! diff --git a/src/jupyter-aou/wbcli/wb b/src/jupyter-aou/wbcli/wb new file mode 100644 index 00000000..9e352b9c --- /dev/null +++ b/src/jupyter-aou/wbcli/wb @@ -0,0 +1,12 @@ +#!/bin/bash + +if [ ! -f /ready ]; then + printf "Waiting for setup to complete..." + until [ -f /ready ]; do sleep 3; printf "." ; done + printf "\n" +fi + +if [ "$1" == "-c" ]; then + shift +fi +/usr/bin/wb $@