Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
Original work done in
jupyterhub/jupyter-remote-desktop-proxy#51,
split out to here.
  • Loading branch information
yuvipanda committed Jan 4, 2024
1 parent e0a2578 commit 4cdcd4b
Show file tree
Hide file tree
Showing 11 changed files with 371 additions and 69 deletions.
34 changes: 34 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
FROM quay.io/jupyter/minimal-notebook:2023-12-25

USER root

COPY setup-scripts /opt/setup-scripts/

# 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 /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}

USER ${NB_UID}

# Setup qgis

RUN mamba install -c conda-forge --yes \
qgis \
qgis-plugin-manager

COPY --chown=1000:1000 setup-qgis-plugins.bash /tmp/setup-qgis-plugins.bash
RUN /tmp/setup-qgis-plugins.bash && rm /tmp/setup-qgis-plugins.bash

COPY qgis.desktop ${DESKTOP_FILES_DIR}/qgis.desktop
COPY qgis.xml ${MIME_FILES_DIR}/qgis.xml
54 changes: 1 addition & 53 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,54 +1,2 @@
# hub-user-image-template :paperclip:
# NASA QGIS image with Linux Desktop

This is a template repository for creating dedicated user images for 2i2c hubs.

## Overall workflow :gear:

The overall workflow is to:

1. Fork this repository to create your image repository

2. Hook your image repository to quay.io

3. Customize the image by editing repo2docker files in your image repository.

Changes can either be done by direct commits to main on your image repository, or through a pull request from a fork of your image repository. Direct commits will build the image and push it to Quay.io. PRs will build the image and offer a link to test it using Binder. Merging the PR will cause a commit on main and therefore trigger a build and push to Quay.io.

4. Configure your Hub to use this new image

### In-depth guide

Checkout the 2i2c docs for an in-depth guide on how to use this template repository to create a custom user image and use it for your hub :arrow_right: https://docs.2i2c.org/en/latest/admin/howto/environment/hub-user-image-template-guide.html.

## About this template repository :information_source:

This template repository enables [jupyterhub/repo2docker-action](https://github.com/jupyterhub/repo2docker-action).
This GitHub action builds a Docker image using the contents of this repo and pushes it to the [Quay.io](https://quay.io/) registry.

### The environment

It provides an example of a `environment.yml` conda configuration file for repo2docker to use.
This file can be used to list all the conda packages that need to be installed by `repo2docker` in your environment.
The `repo2docker-action` will update the [base repo2docker](https://github.com/jupyterhub/repo2docker/blob/HEAD/repo2docker/buildpacks/conda/environment.yml) conda environment with the packages listed in this `environment.yml` file.

**Note:**
A complete list of possible configuration files that can be added to the repository and be used by repo2docker to build the Docker image, can be found in the [repo2docker docs](https://repo2docker.readthedocs.io/en/latest/config_files.html#configuration-files).

### The GitHub Action workflows

This template repository provides some GitHub Action workflows that can build and push the image to quay.io when configured, and test the image on Binder.

![Workflows](images/workflows.png)

#### 1. Build and push container image :arrow_right: [build.yaml](https://github.com/2i2c-org/hub-user-image-template/blob/main/.github/workflows/build.yaml)

This workflow is triggered by every pushed commit on the main branch of the repo (including when a PR is merged), and every commit made to a Pull Request opened against the default branch (`main`)..
It **builds** the image and **pushes** it to the registry _on pushes to the default branch_.
During PR builds, the image is **only** built and **not** pushed, unless explicitly configured to do so.
Checkout [this section](https://docs.2i2c.org/en/latest/admin/howto/environment/hub-user-image-template-guide.html#enable-quay-io-image-push-during-pull-requests) on how to enable image pushes on Pull Requests.

#### 2. Test this PR on Binder Badge :arrow_right: [binder.yaml](https://github.com/2i2c-org/hub-user-image-template/blob/MAIN/.github/workflows/binder.yaml)

This workflow posts a comment inside a pull request, every time a pull request gets opened. The comment contains a "Test this PR on Binder" badge, which can be used to access the image defined by the PR in [mybinder.org](https://mybinder.org/).

![Test this PR on Binder](images/binder-badge.png)
16 changes: 0 additions & 16 deletions environment.yml

This file was deleted.

Binary file removed images/binder-badge.png
Binary file not shown.
Binary file removed images/workflows.png
Binary file not shown.
14 changes: 14 additions & 0 deletions qgis.desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# From: https://github.com/qgis/QGIS/blob/ltr-3_28/linux/org.qgis.qgis.desktop.in
[Desktop Entry]
Type=Application
Name=QGIS Desktop
GenericName=Geographic Information System
Icon=/opt/conda/share/qgis/images/icons/qgis-icon-512x512.png
TryExec=qgis
Exec=qgis %F
Terminal=false
StartupNotify=false
Categories=Qt;Education;Science;Geography;
MimeType=application/x-qgis-project;application/x-qgis-project-container;application/x-qgis-layer-settings;application/x-qgis-layer-definition;application/x-qgis-composer-template;image/tiff;image/jpeg;image/jp2;application/x-raster-aig;application/x-raster-ecw;application/x-raster-mrsid;application/x-mapinfo-mif;application/x-esri-shape;application/vnd.google-earth.kml+xml;application/vnd.google-earth.kmz;application/geopackage+sqlite3;
Keywords=map;globe;postgis;wms;wfs;ogc;osgeo;
StartupWMClass=QGIS3
212 changes: 212 additions & 0 deletions qgis.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
<?xml version="1.0"?>
<!-- From: https://raw.githubusercontent.com/qgis/QGIS/ltr-3_28/debian/qgis.xml -->
<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>

<mime-type type="application/x-qgis-project">
<comment>QGIS Project</comment>
<comment xml:lang="de">QGIS-Projekt</comment>
<sub-class-of type="application/xml"/>
<alias type="application/x-qgis"/>
<icon name="qgis-qgs"/>
<magic priority="50">
<match type="string" offset="0" value="&lt;!DOCTYPE qgis"/>
</magic>
<glob pattern="*.qgs"/>
</mime-type>

<mime-type type="application/x-qgis-project-container">
<comment>QGIS Project</comment>
<comment xml:lang="de">QGIS-Projekt</comment>
<sub-class-of type="application/zip"/>
<alias type="application/x-qgis"/>
<icon name="qgis-qgs"/>
<glob pattern="*.qgz"/>
</mime-type>

<mime-type type="application/x-qgis-layer-settings">
<comment>QGIS layer settings</comment>
<comment xml:lang="de">QGIS-Layereinstellungen</comment>
<sub-class-of type="application/xml"/>
<icon name="qgis-qml"/>
<magic priority="80">
<match type="string" offset="0" value="&lt;!DOCTYPE qgis"/>
</magic>
<glob pattern="*.qml"/>
</mime-type>

<mime-type type="application/x-qgis-layer-definition">
<comment>QGIS layer definition</comment>
<comment xml:lang="de">QGIS-Layerdefinition</comment>
<sub-class-of type="application/xml"/>
<icon name="qgis-qlr"/>
<magic priority="50">
<match type="string" offset="0" value="&lt;!DOCTYPE qgis-layer-definition"/>
</magic>
<glob pattern="*.qlr"/>
</mime-type>

<mime-type type="application/x-qgis-composer-template">
<comment>QGIS composer template</comment>
<comment xml:lang="de">QGIS-Druckzusammenstellungsvorlage</comment>
<sub-class-of type="application/xml"/>
<icon name="qgis-qpt"/>
<magic priority="50">
<match type="string" offset="0" value="&lt;!DOCTYPE qgis"/>
</magic>
<glob pattern="*.qpt"/>
</mime-type>

<mime-type type="application/x-esri-shape">
<comment>ESRI shape file</comment>
<comment xml:lang="de">ESRI-Shapedatei</comment>
<icon name="qgis-mime"/>
<magic priority="100">
<match type="big32" offset="0" value="9994">
<match type="big32" offset="4" value="0">
<match type="big32" offset="8" value="0">
<match type="big32" offset="12" value="0">
<match type="big32" offset="16" value="0">
<match type="big32" offset="20" value="0">
<match type="big32" offset="28" value="1000"/>
</match>
</match>
</match>
</match>
</match>
</match>
</magic>
<glob pattern="*.shp"/>
<glob pattern="*.shx"/>
</mime-type>

<mime-type type="application/x-esri-crs">
<comment>ESRI coordinate reference system</comment>
<comment xml:lang="de">ESRI-Koordinatenreferenzsystem</comment>
<icon name="qgis-mime"/>
<magic>
<match type="string" offset="0" value="GEOGCS["/>
<match type="string" offset="0" value="PROJCS["/>
<match type="string" offset="0" value="LOCAL_CS["/>
</magic>
<glob pattern="*.prj"/>
</mime-type>

<mime-type type="image/tiff">
<comment>TIFF raster data</comment>
<comment xml:lang="de">TIFF-Rasterdaten</comment>
<icon name="qgis-mime"/>
<magic priority="50">
<match type="string" offset="0" value="MM">
<match type="little16" offset="2" value="42"/>
</match>
<match type="string" offset="0" value="MM">
<match type="big16" offset="2" value="42"/>
</match>
</magic>
<glob pattern="*.tiff"/>
<glob pattern="*.tif"/>
</mime-type>

<mime-type type="image/jpeg">
<comment>JPEG raster data</comment>
<comment xml:lang="de">JPEG-Rasterdaten</comment>
<icon name="qgis-mime"/>
<magic priority="50">
<match type="big16" offset="0" value="65496"/>
</magic>
<glob pattern="*.jpeg"/>
<glob pattern="*.jpg"/>
</mime-type>

<mime-type type="image/jp2">
<comment>JPEG2000 raster data</comment>
<comment xml:lang="de">JPEG2000-Rasterdaten</comment>
<icon name="qgis-mime"/>
<magic priority="50">
<match type="little32" offset="0" value="12">
<match type="string" offset="8" value="jP">
<match type="byte" offset="10" value="32">
<match type="byte" offset="11" value="32">
<match type="byte" offset="12" value="13">
<match type="byte" offset="13" value="10">
<match type="byte" offset="14" value="135">
<match type="byte" offset="13" value="10"/>
</match>
</match>
</match>
</match>
</match>
</match>
</match>
</magic>
<glob pattern="*.jp2"/>
<glob pattern="*.j2k"/>
</mime-type>

<mime-type type="application/x-raster-aig">
<comment>AIG raster data</comment>
<comment xml:lang="de">AIG-Rasterdaten</comment>
<icon name="qgis-mime"/>
<glob pattern="*.aig"/>
</mime-type>

<mime-type type="application/x-raster-ecw">
<comment>ECW raster data</comment>
<comment xml:lang="de">ECW-Rasterdaten</comment>
<icon name="qgis-mime"/>
<glob pattern="*.ecw"/>
</mime-type>

<mime-type type="application/x-raster-mrsid">
<comment>MrSID raster data</comment>
<comment xml:lang="de">MrSID-Rasterdaten</comment>
<icon name="qgis-mime"/>
<glob pattern="*.sid"/>
</mime-type>

<mime-type type="application/x-mapinfo-mif">
<comment>MapInfo file</comment>
<comment xml:lang="de">MapInfo-Datei</comment>
<icon name="qgis-mime"/>
<magic priority="51">
<match type="string" offset="0" value="VERSION">
<match type="string" offset="0:512" value="COLUMNS"/>
<match type="string" offset="0:512" value="DATA">
</match>
</match>
</magic>
<glob weight="60" pattern="*.mif"/>
</mime-type>

<!-- .mif is just not good enough -->
<mime-type type="application/x-adobe-mif">
<alias type="application/x-mif"/>
<comment>Adobe FrameMaker MIF file</comment>
<magic priority="100">
<match type="string" offset="0" value="&lt;MIFFile"/>
</magic>
<glob weight="51" pattern="*.mif"/>
</mime-type>

<mime-type type="application/vnd.google-earth.kml+xml">
<comment>Keyhole Markup Language data</comment>
<sub-class-of type="application/xml"/>
<icon name="qgis-mime"/>
<glob pattern="*.kml"/>
</mime-type>

<mime-type type="application/vnd.google-earth.kmz">
<comment>Zipped Keyhole Markup Language data</comment>
<sub-class-of type="application/zip"/>
<icon name="qgis-mime"/>
<glob pattern="*.kmz"/>
</mime-type>

<mime-type type="application/geopackage+sqlite3">
<comment>GeoPackage data</comment>
<sub-class-of type="application/vnd.sqlite3"/>
<icon name="qgis-mime"/>
<glob pattern="*.gpkg"/>
</mime-type>

</mime-info>
18 changes: 18 additions & 0 deletions setup-qgis-plugins.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/bash
# Sets up various QGIS plugins that are useful when running
# on the cloud
set -euo pipefail

# Tell qgis-plugin-manager where our qgis plugins are
export QGIS_PLUGINPATH=/opt/conda/share/qgis/python/plugins

# Install qgis-stac-plugin from our fork, to add support for reading from S3
git clone https://github.com/slesaad/qgis-stac-plugin
cd qgis-stac-plugin
git checkout support_gdal_assets
pip install --no-cache .

python admin.py build
cp -r build/qgis_stac/ ${QGIS_PLUGINPATH}/qgis_stac/
cd ..
rm -rf qgis-stac-plugin
Loading

0 comments on commit 4cdcd4b

Please sign in to comment.