Add support for Julia buildpack
Looks for REQUIRE file in a repo, assumes is Julia
Version pinned to v0.5.2 now - in the future, pick one
based on presence of Julia spec in REQUIRE
Fixes
MODIFY
repo2docker/app.py
repo2docker/app.py
@@ -26,7 +26,7 @@ import subprocess
from .detectors import (
BuildPack, PythonBuildPack, DockerBuildPack, LegacyBinderDockerBuildPack,
- CondaBuildPack, DefaultBuildPack
+ CondaBuildPack, DefaultBuildPack, JuliaBuildPack
)
from .utils import execute_cmd
from . import __version__
@@ -93,7 +93,7 @@ class Repo2Docker(Application):
buildpacks = List(
Type(BuildPack),
- [LegacyBinderDockerBuildPack, DockerBuildPack, CondaBuildPack, PythonBuildPack, DefaultBuildPack],
+ [LegacyBinderDockerBuildPack, DockerBuildPack, CondaBuildPack, PythonBuildPack, JuliaBuildPack, DefaultBuildPack],
config=True,
help="""
Ordered list of BuildPacks to try to use to build a git repository.

MODIFY
repo2docker/detectors.py
repo2docker/detectors.py
@@ -136,6 +136,14 @@ class CondaBuildPack(S2IBuildPack):
return os.path.exists(os.path.join(workdir, 'environment.yml'))
+class JuliaBuildPack(S2IBuildPack):
+ name = Unicode('julia')
+ build_image = Unicode('jupyterhub/singleuser-builder-julia:v0.2.1', config=True)
+
+ def detect(self, workdir):
+ return os.path.exists(os.path.join(workdir, 'REQUIRE'))
+
+
class PythonBuildPack(S2IBuildPack):
"""Build Pack for installing from a pip requirements.txt using S2I"""
name = Unicode('python-pip')

ADD
s2i-builders/julia/Dockerfile
+FROM ubuntu:17.04
+
+MAINTAINER Yuvi Panda <yuvipanda@gmail.com>
+
+LABEL io.openshift.s2i.scripts-url=image:///usr/libexec/s2i
+
+ENV APP_DIR /srv/app
+ENV JULIA_PATH /usr/local/julia
+ENV PATH ${APP_DIR}/venv/bin:$PATH
+
+RUN apt-get update && \
+ apt-get install --yes \
+ python3 \
+ python3-venv \
+ python3-dev \
+ build-essential \
+ pkg-config \
+ libfreetype6-dev \
+ libpng-dev \
+ tar \
+ git \
+ curl \
+ locales && \
+ apt-get purge && apt-get clean
+
+RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \
+ locale-gen
+
+ENV LC_ALL en_US.UTF-8
+ENV LANG en_US.UTF-8
+ENV LANGUAGE en_US.UTF-8
+
+RUN adduser --disabled-password --gecos "Default Jupyter user" jovyan
+
+RUN mkdir -p ${APP_DIR} && chown -R jovyan:jovyan ${APP_DIR}
+
+# Install Julia
+ENV JULIA_PATH /usr/local/julia
+ENV JULIA_VERSION 0.5.2
+
+RUN mkdir $JULIA_PATH && \
+ curl -sSL "https://julialang-s3.julialang.org/bin/linux/x64/${JULIA_VERSION%[.-]*}/julia-${JULIA_VERSION}-linux-x86_64.tar.gz" | tar -xz -C ${JULIA_PATH} --strip-components 1
+
+WORKDIR /home/jovyan
+
+USER jovyan
+RUN python3 -m venv ${APP_DIR}/venv
+
+RUN pip install --no-cache-dir notebook==5.0.0 jupyterhub==0.7.2 ipywidgets==5.2.3 jupyterlab==0.22.1 && \
+ jupyter nbextension enable --py widgetsnbextension --sys-prefix && \
+ jupyter serverextension enable --py jupyterlab --sys-prefix
+
+ENV JUPYTER ${APP_DIR}/venv/bin/jupyter
+ENV PATH ${APP_DIR}/venv/bin:$PATH:${JULIA_PATH}/bin
+ENV JULIA_PKGDIR ${APP_DIR}/.julia
+
+RUN julia -e 'Pkg.init(); Pkg.add("IJulia")' && \
+ mv ${HOME}/.local/share/jupyter/kernels/julia-0.5/ ${APP_DIR}/venv/share/jupyter/kernels/julia-0.5
+
+
+COPY ./s2i/bin/ /usr/libexec/s2i
+
+EXPOSE 8888

ADD
s2i-builders/julia/Makefile
+IMAGE_PREFIX = jupyterhub/singleuser-builder-julia
+VERSION = $(shell cat version)
+
+.PHONY: build
+build:
+ docker build -t $(IMAGE_PREFIX):$(VERSION) . -f Dockerfile
+
+push:
+ docker push "$(IMAGE_PREFIX):$(VERSION)"

ADD
s2i-builders/julia/README.md
+
+# JupyterHub singleuser builder
+
+This is a builder image for use with [s2i](https://github.com/openshift/source-to-image). It
+builds a source repository (such as a github repository) into a docker image that is suitable
+for use with [JupyterHub](http://github.com/jupyterhub/jupyterhub).
+
+It is based off Ubuntu 17.04, and uses [virtualenv](https://pypi.python.org/pypi/virtualenv) to
+provide a custom python3.5 environment.
+
+It looks for a `requirements.txt` file in the source repository, and installs it into the virtualenv.
+It also installs a number of default notebook related modules in there

ADD
s2i-builders/julia/test/run
+#!/bin/bash
+#
+# The 'run' performs a simple test that verifies the S2I image.
+# The main focus here is to exercise the S2I scripts.
+#
+# For more information see the documentation:
+# https://github.com/openshift/source-to-image/blob/master/docs/builder_image.md
+#
+# IMAGE_NAME specifies a name of the candidate image used for testing.
+# The image has to be available before this script is executed.
+#
+IMAGE_NAME=${IMAGE_NAME-ubuntu1610-python35-venv-candidate}
+
+# Determining system utility executables (darwin compatibility check)
+READLINK_EXEC="readlink"
+MKTEMP_EXEC="mktemp"
+if [[ "$OSTYPE" =~ 'darwin' ]]; then
+ ! type -a "greadlink" &>"/dev/null" || READLINK_EXEC="greadlink"
+ ! type -a "gmktemp" &>"/dev/null" || MKTEMP_EXEC="gmktemp"
+fi
+
+test_dir="$($READLINK_EXEC -zf $(dirname "${BASH_SOURCE[0]}"))"
+image_dir=$($READLINK_EXEC -zf ${test_dir}/..)
+scripts_url="file://${image_dir}/.s2i/bin"
+cid_file=$($MKTEMP_EXEC -u --suffix=.cid)
+
+# Since we built the candidate image locally, we don't want S2I to attempt to pull
+# it from Docker hub
+s2i_args="--pull-policy=never --loglevel=2"
+
+# Port the image exposes service to be tested
+test_port=8080
+
+image_exists() {
+ docker inspect $1 &>/dev/null
+}
+
+container_exists() {
+ image_exists $(cat $cid_file)
+}
+
+container_ip() {
+ if [ ! -z "$DOCKER_HOST" ] && [[ "$OSTYPE" =~ 'darwin' ]]; then
+ docker-machine ip
+ else
+ docker inspect --format="{{ .NetworkSettings.IPAddress }}" $(cat $cid_file)
+ fi
+}
+
+container_port() {
+ if [ ! -z "$DOCKER_HOST" ] && [[ "$OSTYPE" =~ 'darwin' ]]; then
+ docker inspect --format="{{(index .NetworkSettings.Ports \"$test_port/tcp\" 0).HostPort}}" "$(cat "${cid_file}")"
+ else
+ echo $test_port
+ fi
+}
+
+run_s2i_build() {
+ s2i build --incremental=true ${s2i_args} file://${test_dir}/test-app ${IMAGE_NAME} ${IMAGE_NAME}-testapp
+}
+
+prepare() {
+ if ! image_exists ${IMAGE_NAME}; then
+ echo "ERROR: The image ${IMAGE_NAME} must exist before this script is executed."
+ exit 1
+ fi
+ # s2i build requires the application is a valid 'Git' repository
+ pushd ${test_dir}/test-app >/dev/null
+ git init
+ git config user.email "build@localhost" && git config user.name "builder"
+ git add -A && git commit -m "Sample commit"
+ popd >/dev/null
+ run_s2i_build
+}
+
+run_test_application() {
+ docker run --rm --cidfile=${cid_file} -p ${test_port} ${IMAGE_NAME}-testapp
+}
+
+cleanup() {
+ if [ -f $cid_file ]; then
+ if container_exists; then
+ docker stop $(cat $cid_file)
+ fi
+ fi
+ if image_exists ${IMAGE_NAME}-testapp; then
+ docker rmi ${IMAGE_NAME}-testapp
+ fi
+}
+
+check_result() {
+ local result="$1"
+ if [[ "$result" != "0" ]]; then
+ echo "S2I image '${IMAGE_NAME}' test FAILED (exit code: ${result})"
+ cleanup
+ exit $result
+ fi
+}
+
+wait_for_cid() {
+ local max_attempts=10
+ local sleep_time=1
+ local attempt=1
+ local result=1
+ while [ $attempt -le $max_attempts ]; do
+ [ -f $cid_file ] && break
+ echo "Waiting for container to start..."
+ attempt=$(( $attempt + 1 ))
+ sleep $sleep_time
+ done
+}
+
+test_usage() {
+ echo "Testing 's2i usage'..."
+ s2i usage ${s2i_args} ${IMAGE_NAME} &>/dev/null
+}
+
+test_connection() {
+ echo "Testing HTTP connection (http://$(container_ip):$(container_port))"
+ local max_attempts=10
+ local sleep_time=1
+ local attempt=1
+ local result=1
+ while [ $attempt -le $max_attempts ]; do
+ echo "Sending GET request to http://$(container_ip):$(container_port)/"
+ response_code=$(curl -s -w %{http_code} -o /dev/null http://$(container_ip):$(container_port)/)
+ status=$?
+ if [ $status -eq 0 ]; then
+ if [ $response_code -eq 200 ]; then
+ result=0
+ fi
+ break
+ fi
+ attempt=$(( $attempt + 1 ))
+ sleep $sleep_time
+ done
+ return $result
+}
+
+# Build the application image twice to ensure the 'save-artifacts' and
+# 'restore-artifacts' scripts are working properly
+prepare
+run_s2i_build
+check_result $?
+
+# Verify the 'usage' script is working properly
+test_usage
+check_result $?
+
+# Verify that the HTTP connection can be established to test application container
+run_test_application &
+
+# Wait for the container to write its CID file
+wait_for_cid
+
+test_connection
+check_result $?
+
+cleanup
+

ADD
s2i-builders/julia/test/test-app/index.html
+
+<!doctype html>
+<html>
+ <head>
+ <title>Hello World!</title>
+ </head>
+ <body>
+ <h1>Hello World!</h1>
+ </body>
+</html>
+
\ No newline at end of file

ADD
s2i-builders/julia/version
+v0.2.1

Add support for Julia buildpack

- Looks for REQUIRE file in a repo, assumes is Julia
- Version pinned to v0.5.2 now - in the future, pick one
  based on presence of Julia spec in REQUIRE

Fixes #23