diff --git a/.travis.yml b/.travis.yml index 31cb359..d5e93da 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,6 +15,7 @@ - make venv script: - set -e + - make build - make test stages: diff --git a/Dockerfile b/Dockerfile index 77e5caa..ff65b03 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,23 +1,32 @@ -FROM jupyter/minimal-notebook:latest +FROM jupyter/minimal-notebook:45bfe5a474fa + +ARG PGWEB_VERSION=0.11.6 USER root RUN apt-get update \ + && apt-get upgrade -y \ && apt-get install -y \ curl \ unzip \ - wget + wget \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* # install pgweb -ENV PGWEB_VERSION=0.11.6 +ENV PGWEB_VERSION="${PGWEB_VERSION}" RUN wget -q "https://github.com/sosedoff/pgweb/releases/download/v${PGWEB_VERSION}/pgweb_linux_amd64.zip" \ && unzip pgweb_linux_amd64.zip -d /usr/bin \ && mv /usr/bin/pgweb_linux_amd64 /usr/bin/pgweb # setup package, enable classic extension, build lab extension USER "${NB_USER}" -WORKDIR "${HOME}" -RUN python3 -m pip install git+https://github.com/illumidesk/jupyter-pgweb-proxy.git -RUN jupyter serverextension enable --sys-prefix jupyter_server_proxy +RUN mkdir -p "/tmp/jupyter-pgweb-proxy" +COPY . "/tmp/jupyter-pgweb-proxy" +WORKDIR "/tmp/jupyter-pgweb-proxy" +RUN python3 -m pip install . \ + && jupyter serverextension enable --sys-prefix jupyter_server_proxy \ + && jupyter labextension install @jupyterlab/server-proxy \ + && jupyter lab build # copy configs, update permissions as root USER root @@ -26,3 +35,5 @@ COPY jupyter_notebook_config.py /etc/jupyter/jupyter_notebook_config.py RUN fix-permissions /etc/jupyter USER "${NB_USER}" + +WORKDIR "${HOME}" \ No newline at end of file diff --git a/Makefile b/Makefile index 6e28829..2d8f537 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,7 @@ help: @grep -E '^[a-zA-Z0-9_%/-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' build: ## build the latest image for a stack - ${VENV_BIN}/jupyter-repo2docker --no-run --user-id 1000 --user-name jovyan --image-name $(OWNER)/pgweb:$(TAG) . + @docker build -t illumidesk/pgweb:latest . @echo -n "Built image size: " @docker images $(OWNER)/pgweb:$(TAG) --format "{{.Size}}" diff --git a/README.md b/README.md index 1f07d83..6229c7c 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,16 @@ This package was built from the [`illumidesk/cookiecutter-jupyter-server-proxy`] ## Requirements -- Python 3.6+ -- Jupyter Notebook 6.0+ -- JupyterLab 2.1+ +- [Python 3.6+](https://www.python.org/downloads/) +- [Jupyter Notebook 6.0+](https://pypi.org/project/notebook/) +- [JupyterLab 2.1+](https://jupyterlab.readthedocs.io/en/stable/getting_started/installation.html) -This package executes the standard `pgweb` command. This command assumes the `pgweb` command is available in the environment's `PATH`. +(Optional) For testing: + +- [Docker](https://docs.docker.com/get-docker/) +- [docker-compose](https://docs.docker.com/compose/install/) + +This package executes the standard `pgweb` command. This command assumes the `pgweb` command is available in the environment's `PATH`. For convenience, the tests include cases that assert outputs when running the `pgweb` command from a docker container. If you don't need to run tests with this setup running in a docker container, then remove the `tests/test_pgweb_docker.py` file or comment out the code in the file. ## What? @@ -28,7 +33,7 @@ This test requires you to have a database instance available as a public endpoin make dev ``` -1. Open your browser: http://localhost:8889 +1. Open your browser: `http://localhost:8889` 1. Click the `pgweb` item from the `New` dropdown in `Jupyter Classic` or click on the green `pgweb` icon in the Notebooks section in `Jupyter Lab`. 1. Connect with the `Scheme` or `Standard` option. diff --git a/jupyter_notebook_config.py b/jupyter_notebook_config.py index 40740aa..99a2625 100644 --- a/jupyter_notebook_config.py +++ b/jupyter_notebook_config.py @@ -10,7 +10,15 @@ "headers": {"Content-Security-Policy": "frame-ancestors 'self' *"}, "cookie_options": {"SameSite": "None", "Secure": True}, } + +# allows running the notebook as root c.NotebookApp.allow_root = True -c.NotebookApp.allow_origin = "*" -c.NotebookApp.token = "" -c.NotebookApp.default_url = "/lab" + +# accepts any origin by default, change to add restrictions +c.NotebookApp.allow_origin = '*' + +# add a token if you would like to run this notebook on a public network +c.NotebookApp.token = '' + +# forward to jupyterlab by default +c.NotebookApp.default_url = '/lab' diff --git a/setup.py b/setup.py index bc71424..4a88002 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ setuptools.setup( name="jupyter-pgweb-proxy", - version="0.2.0", + version="0.2.1", url="https://github.com/illumidesk/jupyter-pgweb-proxy", author="IllumiDesk Team", description="hello@illumidesk.com", diff --git a/tests/test_pgweb.py b/tests/test_pgweb.py index 7e2c542..25bf955 100644 --- a/tests/test_pgweb.py +++ b/tests/test_pgweb.py @@ -1,3 +1,6 @@ +import os +import subprocess + import docker from docker.errors import ContainerError @@ -10,7 +13,7 @@ @pytest.mark.parametrize( - "language,version_output", + "executable,version_output", [ ( "pgweb", @@ -21,19 +24,22 @@ ), ], ) -def test_pgweb_version(language, version_output): +def test_pgweb_version(executable, version_output): """Ensure pweb is available in the PATH and that it returns the correct version""" - LOGGER.info(f"Test that language {language} is correctly installed ...") - client = docker.from_env() - output = client.containers.run("illumidesk/pgweb:latest", f"{language} --version") - output_decoded = output.decode("utf-8").split(" ") + LOGGER.info(f"Test that language {executable} is correctly installed ...") + f = os.popen(f'{executable} --version') + output = f.read() + output_decoded = output.split(" ") assert output_decoded[0:2] == version_output LOGGER.info(f"Output from command: {output_decoded[0:3]}") - + def test_invalid_cmd(): """Ensure that an invalid command returns a docker.errors.ContainerError""" - with pytest.raises(ContainerError): - LOGGER.info("Test an invalid command ...") - client = docker.from_env() - client.containers.run("illumidesk/pgweb", "foo --version") + LOGGER.info("Test an invalid command ...") + f = os.popen(f'foo --version') + output = f.read() + output_decoded = output.split(" ") + assert output_decoded[0:1] != "pgweb" + LOGGER.info(f"Output from command: {output_decoded[0:3]}") + diff --git a/tests/test_pgweb_with_docker.py b/tests/test_pgweb_with_docker.py new file mode 100644 index 0000000..6f33df5 --- /dev/null +++ b/tests/test_pgweb_with_docker.py @@ -0,0 +1,39 @@ +import docker +from docker.errors import ContainerError + +import logging + +import pytest + + +LOGGER = logging.getLogger(__name__) + + +@pytest.mark.parametrize( + "language,version_output", + [ + ( + "pgweb", + [ + "Pgweb", + "v0.11.6", + ], + ), + ], +) +def test_pgweb_version_with_docker(language, version_output): + """Ensure pweb is available in the PATH and that it returns the correct version""" + LOGGER.info(f"Test that language {language} is correctly installed ...") + client = docker.from_env() + output = client.containers.run("illumidesk/pgweb:latest", f"{language} --version") + output_decoded = output.decode("utf-8").split(" ") + assert output_decoded[0:2] == version_output + LOGGER.info(f"Output from command: {output_decoded[0:3]}") + + +def test_invalid_cmd_with_docker(): + """Ensure that an invalid command returns a docker.errors.ContainerError""" + with pytest.raises(ContainerError): + LOGGER.info("Test an invalid command ...") + client = docker.from_env() + client.containers.run("illumidesk/pgweb", "foo --version")