From 4f073d0f4a7f0821e604d17858ef8577fa38f863 Mon Sep 17 00:00:00 2001 From: dogopupper Date: Thu, 1 Feb 2018 00:02:10 +0000 Subject: [PATCH] Add tensorflow-notebook-image dockerfiles --- .../tensorflow-notebook-image/Dockerfile.cpu | 182 ++++++++++++++++++ .../tensorflow-notebook-image/Dockerfile.gpu | 182 ++++++++++++++++++ components/tensorflow-notebook-image/Makefile | 28 +++ .../jupyter_notebook_config.py | 49 +++++ .../start-notebook.sh | 23 +++ .../start-singleuser.sh | 49 +++++ components/tensorflow-notebook-image/start.sh | 65 +++++++ 7 files changed, 578 insertions(+) create mode 100644 components/tensorflow-notebook-image/Dockerfile.cpu create mode 100644 components/tensorflow-notebook-image/Dockerfile.gpu create mode 100644 components/tensorflow-notebook-image/Makefile create mode 100755 components/tensorflow-notebook-image/jupyter_notebook_config.py create mode 100755 components/tensorflow-notebook-image/start-notebook.sh create mode 100755 components/tensorflow-notebook-image/start-singleuser.sh create mode 100755 components/tensorflow-notebook-image/start.sh diff --git a/components/tensorflow-notebook-image/Dockerfile.cpu b/components/tensorflow-notebook-image/Dockerfile.cpu new file mode 100644 index 00000000000..bd6a5b0d479 --- /dev/null +++ b/components/tensorflow-notebook-image/Dockerfile.cpu @@ -0,0 +1,182 @@ +# Copyright (c) Jupyter Development Team. +# Distributed under the terms of the Modified BSD License. +FROM ubuntu:latest + +USER root +# Install all OS dependencies for notebook server that starts but lacks all +# features (e.g., download as all possible file formats) +ENV DEBIAN_FRONTEND noninteractive + +RUN apt-get update && apt-get install -yq --no-install-recommends \ + apt-transport-https \ + build-essential \ + bzip2 \ + ca-certificates \ + curl \ + emacs \ + fonts-liberation \ + g++ \ + git \ + inkscape \ + jed \ + libav-tools \ + libcupti-dev \ + libsm6 \ + libxext-dev \ + libxrender1 \ + lmodern \ + locales \ + lsb-release \ + openssh-client \ + pandoc \ + pkg-config \ + python \ + python-dev \ + sudo \ + unzip \ + vim \ + wget \ + zip \ + zlib1g-dev \ + && apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \ + locale-gen + +# Install Tini +RUN wget --quiet https://github.com/krallin/tini/releases/download/v0.10.0/tini && \ + echo "1361527f39190a7338a0b434bd8c88ff7233ce7b9a4876f3315c22fce7eca1b0 *tini" | sha256sum -c - && \ + mv tini /usr/local/bin/tini && \ + chmod +x /usr/local/bin/tini + +# Configure environment +ENV CONDA_DIR /opt/conda +ENV PATH $CONDA_DIR/bin:$PATH +ENV SHELL /bin/bash +ENV NB_USER jovyan +ENV NB_UID 1000 +ENV HOME /home/$NB_USER +ENV LC_ALL en_US.UTF-8 +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US.UTF-8 + +# Create jovyan user with UID=1000 and in the 'users' group +RUN useradd -m -s /bin/bash -N -u $NB_UID $NB_USER && \ + mkdir -p $CONDA_DIR && \ + chown $NB_USER $CONDA_DIR + +USER $NB_USER + +# Setup work directory for backward-compatibility +RUN mkdir /home/$NB_USER/work + +# Install conda as jovyan and check the md5 sum provided on the download site +ENV MINICONDA_VERSION 4.3.21 +RUN cd /tmp && \ + mkdir -p $CONDA_DIR && \ + wget --quiet https://repo.continuum.io/miniconda/Miniconda3-${MINICONDA_VERSION}-Linux-x86_64.sh && \ + echo "c1c15d3baba15bf50293ae963abef853 *Miniconda3-${MINICONDA_VERSION}-Linux-x86_64.sh" | md5sum -c - && \ + /bin/bash Miniconda3-${MINICONDA_VERSION}-Linux-x86_64.sh -f -b -p $CONDA_DIR && \ + rm Miniconda3-${MINICONDA_VERSION}-Linux-x86_64.sh && \ + $CONDA_DIR/bin/conda config --system --prepend channels conda-forge && \ + $CONDA_DIR/bin/conda config --system --set auto_update_conda false && \ + $CONDA_DIR/bin/conda config --system --set show_channel_urls true && \ + $CONDA_DIR/bin/conda update --all && \ + conda clean -tipsy + +# Install Jupyter Notebook and Hub +RUN conda install --quiet --yes \ + 'notebook=5.0.*' \ + 'jupyterhub=0.8.1' \ + 'jupyterlab=0.24.*' \ + && conda clean -tipsy + +USER root + +EXPOSE 8888 +WORKDIR $HOME + +# Configure container startup +ENTRYPOINT ["tini", "--"] +CMD ["start-notebook.sh"] + +# Add local files as late as possible to avoid cache busting +COPY start.sh /usr/local/bin/ +COPY start-notebook.sh /usr/local/bin/ +COPY start-singleuser.sh /usr/local/bin/ +COPY jupyter_notebook_config.py /etc/jupyter/ +RUN chown -R $NB_USER:users /etc/jupyter/ + +# Install CUDA Profile Tools +RUN pip --no-cache-dir install \ + Pillow \ + h5py \ + ipykernel \ + matplotlib \ + numpy \ + pandas \ + scipy \ + sklearn \ + kubernetes \ + grpcio \ + && \ + python -m ipykernel.kernelspec + +# Install Python 3 packages +# Remove pyqt and qt pulled in for matplotlib since we're only ever going to +# use notebook-friendly backends in these images +RUN conda install --quiet --yes \ + 'nomkl' \ + 'ipywidgets=6.0*' \ + 'pandas=0.19*' \ + 'numexpr=2.6*' \ + 'matplotlib=2.0*' \ + 'scipy=0.19*' \ + 'seaborn=0.7*' \ + 'scikit-learn=0.18*' \ + 'scikit-image=0.12*' \ + 'sympy=1.0*' \ + 'cython=0.25*' \ + 'patsy=0.4*' \ + 'statsmodels=0.8*' \ + 'cloudpickle=0.2*' \ + 'dill=0.2*' \ + 'numba=0.31*' \ + 'bokeh=0.12*' \ + 'sqlalchemy=1.1*' \ + 'hdf5=1.8.17' \ + 'h5py=2.6*' \ + 'vincent=0.4.*' \ + 'beautifulsoup4=4.5.*' \ + 'xlrd' && \ + conda remove --quiet --yes --force qt pyqt && \ + conda clean -tipsy + +# Install Python 3 Tensorflow without GPU support +RUN pip install --quiet --no-cache-dir tf-nightly + +ENV CLOUD_SDK_VERSION 168.0.0 +RUN export CLOUD_SDK_REPO="cloud-sdk-$(lsb_release -c -s)" && \ + echo "deb https://packages.cloud.google.com/apt $CLOUD_SDK_REPO main" > /etc/apt/sources.list.d/google-cloud-sdk.list && \ + curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - && \ + apt-get update && \ + apt-get install -y google-cloud-sdk=${CLOUD_SDK_VERSION}-0 kubectl && \ + gcloud config set core/disable_usage_reporting true && \ + gcloud config set component_manager/disable_update_check true && \ + gcloud config set metrics/environment github_docker_image + +# Activate ipywidgets extension in the environment that runs the notebook server +RUN jupyter nbextension enable --py widgetsnbextension --sys-prefix + +RUN chown -R $NB_USER /home/$NB_USER/ + +RUN curl -L -o bazel.sh https://github.com/bazelbuild/bazel/releases/download/0.8.0/bazel-0.8.0-installer-linux-x86_64.sh && chmod a+x ./bazel.sh && ./bazel.sh && rm ./bazel.sh +USER $NB_USER +RUN git clone https://github.com/tensorflow/models.git /home/$NB_USER/tensorflow-models && git clone https://github.com/tensorflow/benchmarks.git /home/$NB_USER/tensorflow-benchmarks +RUN conda create -n ipykernel_py2 python=2 ipykernel && python -m ipykernel install --user +# Import matplotlib the first time to build the font cache. +ENV XDG_CACHE_HOME /home/$NB_USER/.cache/ +RUN pip install jupyter-tensorboard + +ENV PATH=/home/jovyan/bin:$PATH diff --git a/components/tensorflow-notebook-image/Dockerfile.gpu b/components/tensorflow-notebook-image/Dockerfile.gpu new file mode 100644 index 00000000000..acd344f34a9 --- /dev/null +++ b/components/tensorflow-notebook-image/Dockerfile.gpu @@ -0,0 +1,182 @@ +# Copyright (c) Jupyter Development Team. +# Distributed under the terms of the Modified BSD License. +FROM nvidia/cuda:8.0-cudnn6-devel-ubuntu16.04 + +USER root +# Install all OS dependencies for notebook server that starts but lacks all +# features (e.g., download as all possible file formats) +ENV DEBIAN_FRONTEND noninteractive + +RUN apt-get update && apt-get install -yq --no-install-recommends \ + apt-transport-https \ + build-essential \ + bzip2 \ + ca-certificates \ + curl \ + emacs \ + fonts-liberation \ + g++ \ + git \ + inkscape \ + jed \ + libav-tools \ + libcupti-dev \ + libsm6 \ + libxext-dev \ + libxrender1 \ + lmodern \ + locales \ + lsb-release \ + openssh-client \ + pandoc \ + pkg-config \ + python \ + python-dev \ + sudo \ + unzip \ + vim \ + wget \ + zip \ + zlib1g-dev \ + && apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \ + locale-gen + +# Install Tini +RUN wget --quiet https://github.com/krallin/tini/releases/download/v0.10.0/tini && \ + echo "1361527f39190a7338a0b434bd8c88ff7233ce7b9a4876f3315c22fce7eca1b0 *tini" | sha256sum -c - && \ + mv tini /usr/local/bin/tini && \ + chmod +x /usr/local/bin/tini + +# Configure environment +ENV CONDA_DIR /opt/conda +ENV PATH $CONDA_DIR/bin:$PATH +ENV SHELL /bin/bash +ENV NB_USER jovyan +ENV NB_UID 1000 +ENV HOME /home/$NB_USER +ENV LC_ALL en_US.UTF-8 +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US.UTF-8 + +# Create jovyan user with UID=1000 and in the 'users' group +RUN useradd -m -s /bin/bash -N -u $NB_UID $NB_USER && \ + mkdir -p $CONDA_DIR && \ + chown $NB_USER $CONDA_DIR + +USER $NB_USER + +# Setup work directory for backward-compatibility +RUN mkdir /home/$NB_USER/work + +# Install conda as jovyan and check the md5 sum provided on the download site +ENV MINICONDA_VERSION 4.3.21 +RUN cd /tmp && \ + mkdir -p $CONDA_DIR && \ + wget --quiet https://repo.continuum.io/miniconda/Miniconda3-${MINICONDA_VERSION}-Linux-x86_64.sh && \ + echo "c1c15d3baba15bf50293ae963abef853 *Miniconda3-${MINICONDA_VERSION}-Linux-x86_64.sh" | md5sum -c - && \ + /bin/bash Miniconda3-${MINICONDA_VERSION}-Linux-x86_64.sh -f -b -p $CONDA_DIR && \ + rm Miniconda3-${MINICONDA_VERSION}-Linux-x86_64.sh && \ + $CONDA_DIR/bin/conda config --system --prepend channels conda-forge && \ + $CONDA_DIR/bin/conda config --system --set auto_update_conda false && \ + $CONDA_DIR/bin/conda config --system --set show_channel_urls true && \ + $CONDA_DIR/bin/conda update --all && \ + conda clean -tipsy + +# Install Jupyter Notebook and Hub +RUN conda install --quiet --yes \ + 'notebook=5.0.*' \ + 'jupyterhub=0.8.1' \ + 'jupyterlab=0.24.*' \ + && conda clean -tipsy + +USER root + +EXPOSE 8888 +WORKDIR $HOME + +# Configure container startup +ENTRYPOINT ["tini", "--"] +CMD ["start-notebook.sh"] + +# Add local files as late as possible to avoid cache busting +COPY start.sh /usr/local/bin/ +COPY start-notebook.sh /usr/local/bin/ +COPY start-singleuser.sh /usr/local/bin/ +COPY jupyter_notebook_config.py /etc/jupyter/ +RUN chown -R $NB_USER:users /etc/jupyter/ + +# Install CUDA Profile Tools +RUN pip --no-cache-dir install \ + Pillow \ + h5py \ + ipykernel \ + matplotlib \ + numpy \ + pandas \ + scipy \ + sklearn \ + kubernetes \ + grpcio \ + && \ + python -m ipykernel.kernelspec + +# Install Python 3 packages +# Remove pyqt and qt pulled in for matplotlib since we're only ever going to +# use notebook-friendly backends in these images +RUN conda install --quiet --yes \ + 'nomkl' \ + 'ipywidgets=6.0*' \ + 'pandas=0.19*' \ + 'numexpr=2.6*' \ + 'matplotlib=2.0*' \ + 'scipy=0.19*' \ + 'seaborn=0.7*' \ + 'scikit-learn=0.18*' \ + 'scikit-image=0.12*' \ + 'sympy=1.0*' \ + 'cython=0.25*' \ + 'patsy=0.4*' \ + 'statsmodels=0.8*' \ + 'cloudpickle=0.2*' \ + 'dill=0.2*' \ + 'numba=0.31*' \ + 'bokeh=0.12*' \ + 'sqlalchemy=1.1*' \ + 'hdf5=1.8.17' \ + 'h5py=2.6*' \ + 'vincent=0.4.*' \ + 'beautifulsoup4=4.5.*' \ + 'xlrd' && \ + conda remove --quiet --yes --force qt pyqt && \ + conda clean -tipsy + +# Install Python 3 Tensorflow with GPU support +RUN pip install --quiet --no-cache-dir tf-nightly-gpu + +ENV CLOUD_SDK_VERSION 168.0.0 +RUN export CLOUD_SDK_REPO="cloud-sdk-$(lsb_release -c -s)" && \ + echo "deb https://packages.cloud.google.com/apt $CLOUD_SDK_REPO main" > /etc/apt/sources.list.d/google-cloud-sdk.list && \ + curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - && \ + apt-get update && \ + apt-get install -y google-cloud-sdk=${CLOUD_SDK_VERSION}-0 kubectl && \ + gcloud config set core/disable_usage_reporting true && \ + gcloud config set component_manager/disable_update_check true && \ + gcloud config set metrics/environment github_docker_image + +# Activate ipywidgets extension in the environment that runs the notebook server +RUN jupyter nbextension enable --py widgetsnbextension --sys-prefix + +RUN chown -R $NB_USER /home/$NB_USER/ + +RUN curl -L -o bazel.sh https://github.com/bazelbuild/bazel/releases/download/0.8.0/bazel-0.8.0-installer-linux-x86_64.sh && chmod a+x ./bazel.sh && ./bazel.sh && rm ./bazel.sh +USER $NB_USER +RUN git clone https://github.com/tensorflow/models.git /home/$NB_USER/tensorflow-models && git clone https://github.com/tensorflow/benchmarks.git /home/$NB_USER/tensorflow-benchmarks +RUN conda create -n ipykernel_py2 python=2 ipykernel && python -m ipykernel install --user +# Import matplotlib the first time to build the font cache. +ENV XDG_CACHE_HOME /home/$NB_USER/.cache/ +RUN pip install jupyter-tensorboard + +ENV PATH=/home/jovyan/bin:$PATH diff --git a/components/tensorflow-notebook-image/Makefile b/components/tensorflow-notebook-image/Makefile new file mode 100644 index 00000000000..ad5591befe6 --- /dev/null +++ b/components/tensorflow-notebook-image/Makefile @@ -0,0 +1,28 @@ +# Copyright 2015 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and + +all: container + +TAG?=$(shell git rev-parse HEAD) +REGISTRY?=gcr.io/kubeflow +IMAGE=tensorflow-notebook + +container: + docker build --pull -t ${REGISTRY}/${IMAGE}-cpu:${TAG} -f Dockerfile.cpu . + docker build --pull -t ${REGISTRY}/${IMAGE}-gpu:${TAG} -f Dockerfile.gpu . + +push: + gcloud docker -- push ${REGISTRY}/${IMAGE}-cpu:${TAG} + gcloud docker -- push ${REGISTRY}/${IMAGE}-gpu:${TAG} + +.PHONY: all container push diff --git a/components/tensorflow-notebook-image/jupyter_notebook_config.py b/components/tensorflow-notebook-image/jupyter_notebook_config.py new file mode 100755 index 00000000000..9eb6f20c690 --- /dev/null +++ b/components/tensorflow-notebook-image/jupyter_notebook_config.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from jupyter_core.paths import jupyter_data_dir +import subprocess +import os +import errno +import stat + +c = get_config() +c.NotebookApp.ip = '*' +c.NotebookApp.port = 8888 +c.NotebookApp.open_browser = False + +# Generate a self-signed certificate +if 'GEN_CERT' in os.environ: + dir_name = jupyter_data_dir() + pem_file = os.path.join(dir_name, 'notebook.pem') + try: + os.makedirs(dir_name) + except OSError as exc: # Python >2.5 + if exc.errno == errno.EEXIST and os.path.isdir(dir_name): + pass + else: + raise + # Generate a certificate if one doesn't exist on disk + subprocess.check_call(['openssl', 'req', '-new', + '-newkey', 'rsa:2048', + '-days', '365', + '-nodes', '-x509', + '-subj', '/C=XX/ST=XX/L=XX/O=generated/CN=generated', + '-keyout', pem_file, + '-out', pem_file]) + # Restrict access to the file + os.chmod(pem_file, stat.S_IRUSR | stat.S_IWUSR) + c.NotebookApp.certfile = pem_file diff --git a/components/tensorflow-notebook-image/start-notebook.sh b/components/tensorflow-notebook-image/start-notebook.sh new file mode 100755 index 00000000000..cffb73b5c08 --- /dev/null +++ b/components/tensorflow-notebook-image/start-notebook.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# Copyright 2017 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +if [[ ! -z "${JUPYTERHUB_API_TOKEN}" ]]; then + # launched by JupyterHub, use single-user entrypoint + exec /usr/local/bin/start-singleuser.sh $* +else + . /usr/local/bin/start.sh jupyter notebook $* +fi diff --git a/components/tensorflow-notebook-image/start-singleuser.sh b/components/tensorflow-notebook-image/start-singleuser.sh new file mode 100755 index 00000000000..eb1857455f5 --- /dev/null +++ b/components/tensorflow-notebook-image/start-singleuser.sh @@ -0,0 +1,49 @@ +#!/bin/bash +# Copyright 2017 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +# set default ip to 0.0.0.0 +if [[ "$NOTEBOOK_ARGS $@" != *"--ip="* ]]; then + NOTEBOOK_ARGS="--ip=0.0.0.0 $NOTEBOOK_ARGS" +fi + +# handle some deprecated environment variables +# from DockerSpawner < 0.8. +# These won't be passed from DockerSpawner 0.9, +# so avoid specifying --arg=empty-string +if [ ! -z "$NOTEBOOK_DIR" ]; then + NOTEBOOK_ARGS="--notebook-dir='$NOTEBOOK_DIR' $NOTEBOOK_ARGS" +fi +if [ ! -z "$JPY_PORT" ]; then + NOTEBOOK_ARGS="--port=$JPY_PORT $NOTEBOOK_ARGS" +fi +if [ ! -z "$JPY_USER" ]; then + NOTEBOOK_ARGS="--user=$JPY_USER $NOTEBOOK_ARGS" +fi +if [ ! -z "$JPY_COOKIE_NAME" ]; then + NOTEBOOK_ARGS="--cookie-name=$JPY_COOKIE_NAME $NOTEBOOK_ARGS" +fi +if [ ! -z "$JPY_BASE_URL" ]; then + NOTEBOOK_ARGS="--base-url=$JPY_BASE_URL $NOTEBOOK_ARGS" +fi +if [ ! -z "$JPY_HUB_PREFIX" ]; then + NOTEBOOK_ARGS="--hub-prefix=$JPY_HUB_PREFIX $NOTEBOOK_ARGS" +fi +if [ ! -z "$JPY_HUB_API_URL" ]; then + NOTEBOOK_ARGS="--hub-api-url=$JPY_HUB_API_URL $NOTEBOOK_ARGS" +fi + +. /usr/local/bin/start.sh jupyterhub-singleuser $NOTEBOOK_ARGS $@ diff --git a/components/tensorflow-notebook-image/start.sh b/components/tensorflow-notebook-image/start.sh new file mode 100755 index 00000000000..adb43200087 --- /dev/null +++ b/components/tensorflow-notebook-image/start.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# Copyright 2017 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -e + +# Handle special flags if we're root +if [ $(id -u) == 0 ] ; then + # Handle username change. Since this is cheap, do this unconditionally + usermod -d /home/$NB_USER -l $NB_USER jovyan + + # Change UID of NB_USER to NB_UID if it does not match + if [ "$NB_UID" != $(id -u $NB_USER) ] ; then + echo "Set user UID to: $NB_UID" + usermod -u $NB_UID $NB_USER + # Careful: $HOME might resolve to /root depending on how the + # container is started. Use the $NB_USER home path explicitly. + for d in "$CONDA_DIR" "$JULIA_PKGDIR" "/home/$NB_USER"; do + if [[ ! -z "$d" && -d "$d" ]]; then + echo "Set ownership to uid $NB_UID: $d" + chown -R $NB_UID "$d" + fi + done + fi + + # Change GID of NB_USER to NB_GID if NB_GID is passed as a parameter + if [ "$NB_GID" ] ; then + echo "Change GID to $NB_GID" + groupmod -g $NB_GID -o $(id -g -n $NB_USER) + fi + + # Enable sudo if requested + if [[ "$GRANT_SUDO" == "1" || "$GRANT_SUDO" == 'yes' ]]; then + echo "Granting $NB_USER sudo access" + echo "$NB_USER ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/notebook + fi + + # Exec the command as NB_USER + echo "Execute the command as $NB_USER" + exec su $NB_USER -c "env PATH=$PATH $*" +else + if [[ ! -z "$NB_UID" && "$NB_UID" != "$(id -u)" ]]; then + echo 'Container must be run as root to set $NB_UID' + fi + if [[ ! -z "$NB_GID" && "$NB_GID" != "$(id -g)" ]]; then + echo 'Container must be run as root to set $NB_GID' + fi + if [[ "$GRANT_SUDO" == "1" || "$GRANT_SUDO" == 'yes' ]]; then + echo 'Container must be run as root to grant sudo permissions' + fi + # Exec the command + echo "Execute the command" + exec $* +fi