Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions containers/ilab/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*~

165 changes: 165 additions & 0 deletions containers/ilab/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# this was seeded from https://github.com/umsi-mads/education-notebook/blob/master/Makefile
.PHONY: help build ope root push publish lab nb python-versions distro-versions image-sha clean
.IGNORE: ope root

# see if there is a specified customization in the base settting
SHELL := /bin/bash
CUST := $(shell if [[ -a base/customization_name ]]; then cat base/customization_name; fi)


# Name of the repository
OPE_CONTAINER_NAME := $(shell cat base/ope_container_name)

# USER id
OPE_UID := $(shell cat base/ope_uid)
# GROUP id
OPE_GID := $(shell cat base/ope_gid)
# GROUP name
OPE_GROUP := $(shell cat base/ope_group)


BASE_REG := $(shell cat base/base_registry)/
BASE_IMAGE := $(shell cat base/base_image)
BASE_TAG := $(shell cat base/base_tag)

DATE_TAG := $(shell date +"%m.%d.%y_%H.%M.%S")


# User can be an organization,
OPE_BOOK_USER := $(shell if [[ -a base/ope_book_user ]]; then cat base/ope_book_user; else echo ${USER}; fi)
OPE_BOOK_REG := $(shell cat base/ope_book_registry)/

OPE_BOOK_IMAGE := $(OPE_BOOK_USER)/$(OPE_CONTAINER_NAME)

OPE_BETA_TAG := :beta-$(CUST)
OPE_PUBLIC_TAG := :$(CUST)

BASE_DISTRO_PACKAGES := $(shell cat base/distro_pkgs)
PYTHON_PREREQ_VERSIONS := $(shell cat base/python_prereqs)
PYTHON_INSTALL_PACKAGES := $(shell cat base/python_pkgs)
PIP_INSTALL_PACKAGES := $(shell cat base/pip_pkgs)

# Why if for second and not first?
JUPYTER_ENABLE_EXTENSIONS := $(shell cat base/jupyter_enable_exts)
JUPYTER_DISABLE_EXTENSIONS := $(shell if [[ -a base/jupyter_disable_exts ]]; then cat base/jupyter_disable_exts; fi)


# Set customization
CUSTOMIZE_FROM := $(shell if [[ -a base/customize_from ]]; then cat base/customize_from; else echo ${OPE_BOOK_REG}${OPE_BOOK_IMAGE}; fi)

# <reg>/<ope_project>:<ope_container>-<stable|test>-<customization>-<latest|date>
# quay.io/ucsls:stable-ucsls-burosa2023prod-latest

CUSTOMIZE_NAME := $(CUSTOMIZE_FROM)-test-$(shell cat base/customize_name)

CUSTOMIZE_UID := $(shell cat base/customize_uid)
CUSTOMIZE_GID := $(shell cat base/customize_gid)
CUSTOMIZE_GROUP := $(shell cat base/customize_group)


# we mount here to match openshift
MOUNT_DIR := $(shell cat base/mount_dir)
HOST_DIR := ${HOME}

# extra directories to fix permissions on
EXTRA_CHOWN := $(shell if [[ -a base/extra_chown ]]; then cat base/extra_chown; fi)

help:
# http://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
@grep -E '^[a-zA-Z0-9_%/-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

build: DARGS ?= --build-arg FROM_REG=$(BASE_REG) \
--build-arg FROM_IMAGE=$(BASE_IMAGE) \
--build-arg FROM_TAG=$(BASE_TAG) \
--build-arg OPE_UID=$(OPE_UID) \
--build-arg OPE_GID=$(OPE_GID) \
--build-arg OPE_GROUP=$(OPE_GROUP) \
--build-arg ADDITIONAL_DISTRO_PACKAGES="$(BASE_DISTRO_PACKAGES)" \
--build-arg PYTHON_PREREQ_VERSIONS="$(PYTHON_PREREQ_VERSIONS)" \
--build-arg PYTHON_INSTALL_PACKAGES="$(PYTHON_INSTALL_PACKAGES)" \
--build-arg PIP_INSTALL_PACKAGES="$(PIP_INSTALL_PACKAGES)" \
--build-arg EXTRA_CHOWN="$(EXTRA_CHOWN)"
build: ## Make the image customized appropriately
docker build $(DARGS) $(DCACHING) -t $(OPE_BOOK_REG)$(OPE_BOOK_IMAGE)$(OPE_BETA_TAG) --file base/Build.Dockerfile base

customize: DARGS ?= --build-arg FROM_IMAGE=$(CUSTOMIZE_FROM) \
--build-arg CUSTOMIZE_UID=$(CUSTOMIZE_UID) \
--build-arg CUSTOMIZE_GID=$(CUSTOMIZE_GID) \
--build-arg CUSTOMIZE_GROUP=$(CUSTOMIZE_GROUP) \
--build-arg EXTRA_CHOWN="$(EXTRA_CHOWN)"
customize: ## build a customized deployment image
docker build $(DARGS) $(DCACHING) --rm --force-rm -t $(CUSTOMIZE_NAME) --file base/Customize.Dockerfile base
docker-squash -t $(CUSTOMIZE_NAME) $(CUSTOMIZE_NAME)

push: DARGS ?=
push: ## push private build
# make dated version
docker tag $(OPE_BOOK_REG)$(OPE_BOOK_IMAGE)$(OPE_BETA_TAG) $(OPE_BOOK_REG)$(OPE_BOOK_IMAGE)$(OPE_BETA_TAG)_$(DATE_TAG)
# push to private image repo
docker push $(OPE_BOOK_REG)$(OPE_BOOK_IMAGE)$(OPE_BETA_TAG)_$(DATE_TAG)
# push to update tip to current version
docker push $(OPE_BOOK_REG)$(OPE_BOOK_IMAGE)$(OPE_BETA_TAG)

pull-beta: DARGS ?=
pull-beta: ## pull most recent private version
docker pull $(OPE_BOOK_REG)$(OPE_BOOK_IMAGE)$(OPE_BETA_TAG)

publish: pull-beta
publish: DARGS ?=
publish: ## publish current private build to public published version
# make dated version
docker tag $(OPE_BOOK_REG)$(OPE_BOOK_IMAGE)$(OPE_BETA_TAG) $(OPE_BOOK_REG)$(OPE_BOOK_IMAGE)$(OPE_PUBLIC_TAG)_$(DATE_TAG)
# push to private image repo
docker push $(OPE_BOOK_REG)$(OPE_BOOK_IMAGE)$(OPE_PUBLIC_TAG)_$(DATE_TAG)
# copy to tip version
docker tag $(OPE_BOOK_REG)$(OPE_BOOK_IMAGE)$(OPE_BETA_TAG) $(OPE_BOOK_REG)$(OPE_BOOK_IMAGE)$(OPE_PUBLIC_TAG)
# push to update tip to current version
docker push $(OPE_BOOK_REG)$(OPE_BOOK_IMAGE)$(OPE_PUBLIC_TAG)

checksum: ARGS ?= find / -not \( -path /proc -prune \) -not \( -path /sys -prune \) -type f -exec stat -c '%n %a' {} + | LC_ALL=C sort | sha256sum | cut -c 1-64
checksum: DARGS ?= -u 0
checksum: ## start private version with root shell to do admin and poke around
@-docker run -i --rm $(DARGS) $(OPE_BOOK_REG)$(OPE_BOOK_IMAGE)$(OPE_BETA_TAG) $(ARGS)

run-beta: ARGS ?=
run-beta: DARGS ?= -u $(OPE_UID):$(OPE_GID) -v "${HOST_DIR}":"${MOUNT_DIR}" -v "${SSH_AUTH_SOCK}":"${SSH_AUTH_SOCK}" -v "${SSH_AUTH_SOCK}":"${SSH_AUTH_SOCK}" -e SSH_AUTH_SOCK=${SSH_AUTH_SOCK} -p ${SSH_PORT}:22
run-beta: PORT ?= 8888
run-beta: ## start published version with jupyter lab interface
docker run -i --rm -p $(PORT):$(PORT) $(DARGS) $(OPE_BOOK_REG)$(OPE_BOOK_IMAGE)$(OPE_BETA_TAG) $(ARGS)

show-tag: ARGS ?=
show-tag: DARGS ?=
show-tag: ## tag current private build as beta
@-echo $(OPE_BOOK_REG)$(OPE_BOOK_IMAGE)$(OPE_BETA_TAG)


### DEBUG TARGETS
root: ARGS ?= /bin/bash
root: DARGS ?= -u 0
root: ## start private version with root shell to do admin and poke around
-docker run -it --rm $(DARGS) $(OPE_BOOK_REG)$(OPE_BOOK_IMAGE)$(OPE_BETA_TAG) $(ARGS)

user: ARGS ?= /bin/bash
user: DARGS ?=
user: ## start private version with usershell to poke around
-docker run -it --rm $(DARGS) $(OPE_BOOK_REG)$(OPE_BOOK_IMAGE)$(OPE_BETA_TAG) $(ARGS)


### PUBLIC USAGE TARGETS
pull:
pull: ## pull most recent public version
docker pull $(OPE_BOOK_REG)$(OPE_BOOK_IMAGE)$(OPE_PUBLIC_TAG)

# TODO: Cut out SSH port
run: pull
run: ARGS ?=
run: DARGS ?= -u $(OPE_UID):$(OPE_GID) -v "${HOST_DIR}":"${MOUNT_DIR}" -v "${SSH_AUTH_SOCK}":"${SSH_AUTH_SOCK}" -v "${SSH_AUTH_SOCK}":"${SSH_AUTH_SOCK}" -e SSH_AUTH_SOCK=${SSH_AUTH_SOCK}
run: PORT ?= 8888
run: ## start published version with jupyter lab interface
docker run -it --rm -p $(PORT):$(PORT) $(DARGS) $(OPE_BOOK_REG)$(OPE_BOOK_IMAGE)$(OPE_PUBLIC_TAG) $(ARGS)

run-cust: ARGS ?=
run-cust: DARGS ?= -u $(CUSTOMIZE_UID):$(CUSTOMIZE_GID) -v "${HOST_DIR}":"${MOUNT_DIR}" -v "${SSH_AUTH_SOCK}":"${SSH_AUTH_SOCK}" -v "${SSH_AUTH_SOCK}":"${SSH_AUTH_SOCK}" -e SSH_AUTH_SOCK=${SSH_AUTH_SOCK}
run-cust: PORT ?= 8888
run-cust: ## start published version with jupyter lab interface
docker run -it --rm -p $(PORT):$(PORT) $(DARGS) $(CUSTOMIZE_NAME) $(ARGS)
5 changes: 5 additions & 0 deletions containers/ilab/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Description

Container template for OPE project


150 changes: 150 additions & 0 deletions containers/ilab/base/Build.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
## Dockerfile for constructing the base Open Education Effort (OPE)
## container. This container contains everything required for authoring OPE courses
## Well is should anyway ;-)

ARG FROM_REG
ARG FROM_IMAGE
ARG FROM_TAG

FROM ${FROM_REG}${FROM_IMAGE}${FROM_TAG}

LABEL maintainer="Open Education <opeffort@gmail.com>"

# ARGS are consumed and reset after FROM
# so any arguments you want to use below must be stated below FROM

ARG ADDITIONAL_DISTRO_PACKAGES
ARG PYTHON_PREREQ_VERSIONS
ARG PYTHON_INSTALL_PACKAGES

ARG JUPYTER_ENABLE_EXTENSIONS
ARG JUPYTER_DISABLE_EXTENSIONS

# Fix: https://github.com/hadolint/hadolint/wiki/DL4006
# Fix: https://github.com/koalaman/shellcheck/wiki/SC3014
SHELL ["/bin/bash", "-o", "pipefail", "-c"]

# Add a "USER root" statement followed by RUN statements to install system packages using apt-get,
# change file permissions, etc.

# install linux packages that we require for pdf authoring
USER root

RUN dpkg --add-architecture i386 && \
apt-get -y update --fix-missing && \
apt-get -y install ${ADDITIONAL_DISTRO_PACKAGES} && \
apt-get clean && rm -rf /var/lib/apt/lists/*

# Now that distro packages are installed lets install the python packages we want
# This was inspired by
# https://github.com/jupyter/docker-stacks/blob/b186ce5fea6aa9af23fb74167dca52908cb28d71/scipy-notebook/Dockerfile

USER ${NB_UID}

# sometimes there are problems with the existing version of installed python packages
# these need to be installed to the prerequisite versions before we can install the rest of the
# packages. Install Python 3 packages
#RUN python --version

RUN mamba install --yes python=3.9.13 --no-pin --force-reinstall && \
mamba install --yes ${PYTHON_PREREQ_VERSIONS} && \
mamba install --yes ${PYTHON_INSTALL_PACKAGES} && \
mamba install --yes jupyterlab_rise==0.42.0 && \
fix-permissions "${CONDA_DIR}" && \
fix-permissions "/home/${NB_USER}" && \
mamba clean -afy

# Import matplotlib the first time to build the font cache.
ENV XDG_CACHE_HOME="/home/${NB_USER}/.cache/"

# enable extensions
RUN for ext in ${JUPYTER_ENABLE_EXTENSIONS} ; do \
jupyter nbextension enable "$ext" ; \
done && \
fix-permissions "${CONDA_DIR}" && \
fix-permissions "/home/${NB_USER}"

RUN pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu

RUN pip install instructlab

# disable extensions -- disabling core extensions can be really useful for customizing
# jupyterlab user experience
RUN for ext in ${JUPYTER_DISABLE_EXTENSIONS} ; do \
jupyter labextension disable "$ext" ; \
done && \
fix-permissions "${CONDA_DIR}" && \
fix-permissions "/home/${NB_USER}"

# copy overrides.json
COPY settings ${CONDA_DIR}/share/jupyter/lab/settings

USER root

RUN mkdir /home/ope && \
cd /home/ope && \
git clone https://github.com/OPEFFORT/tools.git . && \
./install.sh && \
chown jovyan /home/ope && \
fix-permissions /home/ope

RUN mkdir /home/instructlab && \
cd /home/instructlab && \
chown jovyan /home/instructlab && \
chmod -R 777 /home/instructlab && \
_ILAB_COMPLETE=bash_source ilab > ~/.ilab-complete.bash && \
echo ". ~/.ilab-complete.bash" >> ~/.bashrc

# final bits of cleanup
RUN touch /home/${NB_USER}/.hushlogin && \
# use a short prompt to improve default behaviour in presentations
echo "export PS1='\$ '" >> /home/${NB_USER}/.bashrc && \
# work around bug when term is xterm and emacs runs in xterm.js -- causes escape characters in file
echo "export TERM=linux" >> /home/${NB_USER}/.bashrc && \
# finally remove default working directory from joyvan home
rmdir /home/${NB_USER}/work && \
# as per the nbstripout readme we setup nbstripout be always be used for the joyvan user for all repos
nbstripout --install --system

# Static Customize for OPE USER ID choices
# To avoid problems with start.sh logic we do not modify user name
# FIXME: Add support for swinging home directory if you want to point to a mounted volume
ARG OPE_UID
ENV NB_UID=${OPE_UID}

ARG OPE_GID
ENV NB_GID=${OPE_GID}

ARG OPE_GROUP
ENV NB_GROUP=${OPE_GROUP}

ARG EXTRA_CHOWN
ARG CHOWN_HOME=yes
ARG CHOWN_HOME_OPTS="-R"
ARG CHOWN_EXTRA_OPTS='-R'
ARG CHOWN_EXTRA="${EXTRA_CHOWN} ${CONDA_DIR}"

# Done customization

# jupyter-stack contains logic to run custom start hook scripts from
# two locations -- /usr/local/bin/start-notebook.d and
# /usr/local/bin/before-notebook.d
# and scripts in these directories are run automatically
# an opportunity to set things up based on dynamic facts such as user name

RUN /usr/local/bin/start.sh true; \
echo "hardcoding $NB_USER to uid=$NB_UID and group name $NB_GROUP with gid=$NB_GID shell to /bin/bash" ; \
usermod -s /bin/bash $NB_USER ; \
[[ -w /etc/passwd ]] && echo "Removing write access to /etc/passwd" && chmod go-w /etc/passwd

COPY start-notebook.d /usr/local/bin/start-notebook.d

ENV USER=$NB_USER

# Change the ownership of the home directory to ope group so it starts up properly

RUN chgrp ${OPE_GROUP} -R /home

USER $NB_USER

CMD ["/bin/bash", "-c", "cd /home/jovyan ; start-notebook.sh"]
49 changes: 49 additions & 0 deletions containers/ilab/base/Customize.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
## Dockerfile for constructing the base Open Education Effort (OPE)
## container. This container contains everything required for authoring OPE courses
## Well is should anyway ;-)

ARG FROM_IMAGE

FROM ${FROM_IMAGE}

USER root

# Static Customize for OPE USER ID choices
# To avoid problems with start.sh logic we do not modify user name
# FIXME: Add support for swinging home directory if you want to point to a mounted volume

ARG CUSTOMIZE_UID
ENV NB_UID=${CUSTOMIZE_UID}

ARG CUSTOMIZE_GID
ENV NB_GID=${CUSTOMIZE_GID}

ARG CUSTOMIZE_GROUP
ENV NB_GROUP=${CUSTOMIZE_GROUP}

ARG EXTRA_CHOWN
ARG CHOWN_HOME=yes
ARG CHOWN_HOME_OPTS="-R"
ARG CHOWN_EXTRA_OPTS='-R'
ARG CHOWN_EXTRA="${EXTRA_CHOWN} ${CONDA_DIR}"

# Done customization

# jupyter-stack contains logic to run custom start hook scripts from
# two locations -- /usr/local/bin/start-notebook.d and
# /usr/local/bin/before-notebook.d
# and scripts in these directories are run automatically
# an opportunity to set things up based on dynamic facts such as user name

# # use built in startup script to setup new user home
RUN /usr/local/bin/start.sh true; \
echo "hardcoding $NB_USER to uid=$NB_UID and group name $NB_GROUP with gid=$NB_GID shell to /bin/bash" ; \
usermod -s /bin/bash $NB_USER ; \
[[ -w /etc/passwd ]] && echo "Removing write access to /etc/passwd" && chmod go-w /etc/passwd



USER $NB_USER


CMD ["/bin/bash", "-c", "cd /home/jovyan ; start-notebook.sh"]
1 change: 1 addition & 0 deletions containers/ilab/base/base_image
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
jupyter/minimal-notebook
2 changes: 2 additions & 0 deletions containers/ilab/base/base_registry
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
docker.io

1 change: 1 addition & 0 deletions containers/ilab/base/base_tag
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:x86_64-python-3.9.13
2 changes: 2 additions & 0 deletions containers/ilab/base/checksum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fb2cc759cef3e1a8dd909c66373991a5f028f0bc6b2fcb76bdc7a5b04683b6a5

1 change: 1 addition & 0 deletions containers/ilab/base/customization_name
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
base-ope-image
1 change: 1 addition & 0 deletions containers/ilab/base/customize_from
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
quay.io/opeffort/ope-test:base-ope-image
1 change: 1 addition & 0 deletions containers/ilab/base/customize_gid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
Loading