diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2704d91..faa208a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -20,6 +20,7 @@ include: - DOCKERFILE_RELPATH: "geolab-gpu" # - DOCKERFILE_RELPATH: "mspass_shortcourse" # - DOCKERFILE_RELPATH: "mt_shortcourse" + - DOCKERFILE_RELPATH: "virtual_desktop" variables: CONTAINER_REGISTRY_PLATFORM: "AWS-PUB" diff --git a/docs/.readthedocs.yaml b/docs/.readthedocs.yaml index 1cca7cb..b5f292f 100644 --- a/docs/.readthedocs.yaml +++ b/docs/.readthedocs.yaml @@ -4,6 +4,7 @@ build: os: ubuntu-22.04 tools: python: "3.12" + nodejs: "20" jobs: pre_build: # Generate the Sphinx configuration for this Jupyter Book so it builds. diff --git a/docs/requirements.txt b/docs/requirements.txt index 0027694..aabfd4c 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,4 @@ -jupyter-book +jupyter-book<2.0.0 matplotlib numpy sphinx == 6.2.1 \ No newline at end of file diff --git a/virtual_desktop/Dockerfile b/virtual_desktop/Dockerfile new file mode 100644 index 0000000..58ef15d --- /dev/null +++ b/virtual_desktop/Dockerfile @@ -0,0 +1,51 @@ +FROM public.ecr.aws/earthscope-dev/geolab/geolab-default:agu_wkshp-dc9cd124 AS stage + +ENV NB_GID=1000 + +FROM stage + +USER root + +COPY setup-scripts/setup-linux-desktop.bash /opt/setup-scripts/setup-linux-desktop.bash +COPY setup-scripts/fix-permissions.bash /usr/local/bin/fix-permissions.bash + +# Set DISPLAY env variable, so processes know where to open GUI windows. +# Allows python processes running in notebooks to open windows in the GUI. +ENV DISPLAY=":1.0" + +# Setup Linux Desktop +RUN chmod a+x /opt/setup-scripts/setup-linux-desktop.bash +RUN chmod a+x /usr/local/bin/fix-permissions.bash + +RUN /opt/setup-scripts/setup-linux-desktop.bash + +COPY startup-scripts /usr/local/bin/start-notebook.d/ + +# env variables used by downstream images for setting up desktop files or +# mime associations. Consumed by the startup-scripts in startup-scripts/ +ENV DESKTOP_FILES_DIR=/opt/desktop-files +ENV MIME_FILES_DIR=/opt/mime-files + +RUN mkdir -p ${DESKTOP_FILES_DIR} ${MIME_FILES_DIR} + +#install GMT +RUN apt-get update -qq --yes > /dev/null \ + && apt-get install --yes -qq gnupg2 > /dev/null \ + && apt-get install gcc --yes \ + && apt-get install gfortran --yes \ + && apt-get install g++ --yes \ + && apt-get install make \ + && apt-get install ftp --yes \ + # && apt-get install gmt gmt-dcw gmt-gshhg --yes\ + # && apt-get install gedit --yes \ + # && apt-get install man-db --yes \ + # && apt-get install taup \ + && apt-get clean + +USER ${NB_UID} + +# Pin jupyterhub and pydantic to older version +# because of https://github.com/NASA-IMPACT/veda-jupyterhub/issues/52#issuecomment-2277453902 +RUN python -m pip install --no-cache "jupyterhub<5.0.0" "pydantic<2.0" +RUN python -m pip install --no-cache jupyter-remote-desktop-proxy +# RUN python -m pip install --no-cache git+https://github.com/sunu/jupyter-remote-qgis-proxy@e1a49e0ba98700c2f49fc092d5fc1e43ca5442eb \ No newline at end of file diff --git a/virtual_desktop/environment.yml b/virtual_desktop/environment.yml new file mode 100644 index 0000000..3603735 --- /dev/null +++ b/virtual_desktop/environment.yml @@ -0,0 +1,33 @@ +# Environment we need *on top* of base PANGEO stack +# Get list of pangeo packages from https://github.com/pangeo-data/pangeo-docker-images/blob/master/pangeo-notebook/packages.txt +# BUT REMEMBER TO PICK THE HASH THAT CORRESPONDS TO OUR BASE IMAGE +channels: + - conda-forge + +dependencies: + # Packages required by ES + - tiledb + - pip + - pip: + # Pin jupyterhub and pydantic to older version because of https://github.com/NASA-IMPACT/veda-jupyterhub/issues/52#issuecomment-2277453902 + - awswrangler + - dascore + - earthscope-sdk==1.2.0b0 + - earthscope-cli==1.0.1 + - earthscopestraintools + - hypoinvpy + - gnssrefl + - jupyter_contrib_nbextensions + # - jupyterlab_jupyterbook_navigation + - jupyter-remote-desktop-proxy + - jupyter-resource-usage + - jupyter-server-proxy + # - jupyterhub<5.0.0 + - nbgitpuller + - obspy==1.4.1 + # - pydantic<2.0 + - pygmt==0.14.2 + - pynlloc + - pyocto + - pyrocko + - websockify diff --git a/virtual_desktop/setup-scripts/fix-permissions.bash b/virtual_desktop/setup-scripts/fix-permissions.bash new file mode 100644 index 0000000..d540462 --- /dev/null +++ b/virtual_desktop/setup-scripts/fix-permissions.bash @@ -0,0 +1,33 @@ +#!/bin/bash +# Set permissions on a directory +# After any installation, if a directory needs to be (human) user-writable, run this script on it. +# It will make everything in the directory owned by the group ${NB_GID} and writable by that group. +# Deployments that want to set a specific user id can preserve permissions +# by adding the `--group-add users` line to `docker run`. + +# Uses find to avoid touching files that already have the right permissions, +# which would cause a massive image explosion + +# Right permissions are: +# group=${NB_GID} +# AND permissions include group rwX (directory-execute) +# AND directories have setuid,setgid bits set + +set -e + +for d in "$@"; do + find "${d}" \ + ! \( \ + -group "${NB_GID}" \ + -a -perm -g+rwX \ + \) \ + -exec chgrp "${NB_GID}" -- {} \+ \ + -exec chmod g+rwX -- {} \+ + # setuid, setgid *on directories only* + find "${d}" \ + \( \ + -type d \ + -a ! -perm -6000 \ + \) \ + -exec chmod +6000 -- {} \+ +done \ No newline at end of file diff --git a/virtual_desktop/setup-scripts/setup-linux-desktop.bash b/virtual_desktop/setup-scripts/setup-linux-desktop.bash new file mode 100644 index 0000000..afcd8ce --- /dev/null +++ b/virtual_desktop/setup-scripts/setup-linux-desktop.bash @@ -0,0 +1,59 @@ +#!/bin/bash +set -exuo pipefail +# Requirements: +# - Run as the root user + +# Install baseline packages to get X and xfce working +apt-get update -qq --yes > /dev/null +apt-get install --yes --no-install-recommends -qq \ + xfce4 \ + xorg \ + dbus-x11 \ + xubuntu-icon-theme \ + > /dev/null + +# Install tigervnc from apt repos - these are newer and more architecture +# appropriate than whatever is bundled with jupyter-remote-desktop-proxy +apt-get install --yes --no-install-recommends -qq \ + tigervnc-standalone-server \ + tigervnc-xorg-extension > /dev/null + +# Install add-apt-repositories so we can add PPA for latest firefox +apt-get install --yes --no-install-recommends -qq \ + software-properties-common gpg-agent > /dev/null + +# Install Firefox from a PPA - default Ubuntu's Firefox no longer +# provides it via apt, using snap instead. That does not work inside +# containers. We do this before our apt update in the script so that +# needs to run only once. +add-apt-repository ppa:mozillateam/ppa + +# Install Firefox from the PPA explicitly +apt-get update -qq --yes > /dev/null +apt-get install -qq --yes -t 'o=LP-PPA-mozillateam' --yes firefox + +#install GMT +apt-get install gmt gmt-dcw gmt-gshhg --yes +apt-get install gedit --yes +apt-get install man-db --yes + +#install java and taup +apt-get install -y openjdk-11-jre-headless +wget https://zenodo.org/records/16884103/files/TauP-3.1.0.zip +unzip TauP-3.1.0.zip +export PATH="$PATH:TauP-3.1.0/bin" + +# Cleanup apt-get update side effects +rm -rf /var/lib/apt/lists/* + +# Install packages required for linux desktop VPN setup to work +# websockify and jupyter-server-proxy available from conda-forge, but +# jupyter-remote-desktop-proxy is not. +# Temporarily install nbgitpuller too, while we work on getting it upstream +mamba install -c conda-forge --yes \ + websockify \ + jupyter-server-proxy \ + nbgitpuller + +/usr/local/bin/fix-permissions.bash "${CONDA_DIR}" +/usr/local/bin/fix-permissions.bash "/home/${NB_USER}" \ No newline at end of file diff --git a/virtual_desktop/startup-scripts/setup-mime-files.bash b/virtual_desktop/startup-scripts/setup-mime-files.bash new file mode 100644 index 0000000..5123b4d --- /dev/null +++ b/virtual_desktop/startup-scripts/setup-mime-files.bash @@ -0,0 +1,19 @@ +#!/bin/bash -l +set -euo pipefail +# This script is run on container startup, as a non-root user +# It copies any .xml files it may find in a MIME_FILES_DIR to the user's +# mime associations directory, allowing image authors to allow users to launch +# a specific application by double clicking files of a specific type. +# It's done at startup time because $HOME is often mounted over by a +# persistent remote filesystem, hiding whatever is in the directory. + +# Set nullglob, so we don't error out if there are no MIME files to be found +shopt -s nullglob + +MIME_DIR="${HOME}/.local/share/mime" +MIME_PACKAGES_DIR="${MIME_DIR}/packages" +mkdir -p "${MIME_PACKAGES_DIR}" +for mime_file_path in ${MIME_FILES_DIR}/*.xml; do + cp "${mime_file_path}" "${MIME_PACKAGES_DIR}/." +done +update-mime-database "${MIME_DIR}" \ No newline at end of file