From 378a7c0f84729042575830730ed6c17893c08574 Mon Sep 17 00:00:00 2001 From: Blazej Michalik Date: Sun, 21 Mar 2021 01:17:48 +0100 Subject: [PATCH 01/17] Fix CHANGELOG 1.0.2 URL --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c816e1f..dec20fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,6 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - First working version of `dockernel install` and `dockernel start`. [unreleased]: https://github.com/mrmino/dockernel/v1.0.2...HEAD -[1.0.1]: https://github.com/mrmino/dockernel/releases/tag/v1.0.2 +[1.0.2]: https://github.com/mrmino/dockernel/releases/tag/v1.0.2 [1.0.1]: https://github.com/mrmino/dockernel/releases/tag/v1.0.1 [1.0.0]: https://github.com/mrmino/dockernel/releases/tag/v1.0.0 From b68d4961b2de94273f72436935f6c1953b544f8f Mon Sep 17 00:00:00 2001 From: Blazej Michalik Date: Sun, 21 Mar 2021 01:59:38 +0100 Subject: [PATCH 02/17] Clean up a lint in cli.install --- dockernel/cli/install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockernel/cli/install.py b/dockernel/cli/install.py index 488a18e..36f6d6c 100644 --- a/dockernel/cli/install.py +++ b/dockernel/cli/install.py @@ -49,7 +49,7 @@ def python_argv(system_type: str) -> List[str]: def generate_kernelspec_argv(image_name: str, system_type: str) -> List[str]: dockernel_argv = ['dockernel', 'start', - image_name, JUPYTER_CONNECTION_FILE_TEMPLATE] + image_name, JUPYTER_CONNECTION_FILE_TEMPLATE] return python_argv(system_type) + dockernel_argv From 24ae14f86d044fe7a523a53f66c3a695d2bb8b80 Mon Sep 17 00:00:00 2001 From: Blazej Michalik Date: Sun, 21 Mar 2021 02:00:20 +0100 Subject: [PATCH 03/17] Localize argv-gen tests to Linux --- tests/test_install.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_install.py b/tests/test_install.py index f5f31f8..424d5cd 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -4,12 +4,13 @@ from dockernel.cli import main_arguments -class TestKernelspecArgvGeneration: +# TODO Add tests for Darwin and Windows +class TestLinuxKernelspecArgvGeneration: IMAGE_NAME = 'example/image-name' @pytest.fixture def argv(self): - return generate_kernelspec_argv(self.IMAGE_NAME) + return generate_kernelspec_argv(self.IMAGE_NAME, 'Linux') def test_argv_starts_with_usr_bin_env_python_m(self, argv): assert argv[:3] == ['/usr/bin/env', 'python', '-m'] From f021120b709dd3ce67ec652fd9321c8799bf214f Mon Sep 17 00:00:00 2001 From: Blazej Michalik Date: Sun, 21 Mar 2021 02:00:48 +0100 Subject: [PATCH 04/17] Fix kernelspec tests throwing TypeErrors --- tests/test_kernelspec.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tests/test_kernelspec.py b/tests/test_kernelspec.py index 32cba82..354b329 100644 --- a/tests/test_kernelspec.py +++ b/tests/test_kernelspec.py @@ -1,3 +1,4 @@ +import os import pytest import json from dockernel.kernelspec import (Kernelspec, InterruptMode, @@ -7,6 +8,16 @@ from pathlib import Path +@pytest.yield_fixture +def environment_variables(): + starting_state = os.environ.copy() + + yield os.environ + + os.environ.clear() + os.environ.update(starting_state) + + @pytest.fixture def tmpdir(tmpdir): """Workaround for tmpdir being py.path.LocalPath instead of Path""" @@ -81,7 +92,10 @@ def test_raises_ValueError_when_directory_name_is_not_store(self, tmpdir): class TestKernelspecStoreDir: @pytest.mark.parametrize('system_type', ('Linux', 'Windows', 'Darwin')) - def test_works_for_supported_platforms(self, system_type): + def test_works_for_supported_platforms(self, system_type, + environment_variables): + if system_type == 'Windows': + environment_variables['APPDATA'] = '' user_kernelspec_store(system_type) def test_raises_TypeError_on_unknown_system(self): From ef054786e5c56d31c8691e3cafda8bb85acb3107 Mon Sep 17 00:00:00 2001 From: Blazej Michalik Date: Sun, 21 Mar 2021 02:18:17 +0100 Subject: [PATCH 05/17] Remove unnecessary "cat" from example dockerfile --- example_dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example_dockerfile b/example_dockerfile index 7dfb2cd..b810b9a 100644 --- a/example_dockerfile +++ b/example_dockerfile @@ -1,4 +1,4 @@ FROM python:3.7-slim-buster RUN pip install --upgrade pip ipython ipykernel -CMD cat $DOCKERNEL_CONNECTION_FILE; python -m ipykernel_launcher -f $DOCKERNEL_CONNECTION_FILE || true +CMD python -m ipykernel_launcher -f $DOCKERNEL_CONNECTION_FILE || true From 9de21b9ad76dff710d0b6e04223368dd5dbdeed1 Mon Sep 17 00:00:00 2001 From: Blazej Michalik Date: Sun, 21 Mar 2021 03:11:36 +0100 Subject: [PATCH 06/17] Mention permissions in the README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0cf8692..b6ed66d 100644 --- a/README.md +++ b/README.md @@ -28,9 +28,11 @@ To build your image, use `docker build`. E.g. to build the example mentioned above: ``` -sudo docker build --tag my_kernel - < example_dockerfile +docker build --tag my_kernel - < example_dockerfile ``` +_*Note*: Use `sudo` if you run into permission errors._ + After that, use Dockernel to install the docker image as a Jupyter kernel: ``` From 081d0da5cb78afb776b7e4014cd995b082943c82 Mon Sep 17 00:00:00 2001 From: Blazej Michalik Date: Mon, 22 Mar 2021 01:02:34 +0100 Subject: [PATCH 07/17] Improve Docker permission issues note --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b6ed66d..c6c0746 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,13 @@ different one. ## Usage +_Note for Linux users: + +If you run into permission errors with `docker` or `dockernel` - either use +`sudo`, or follow the steps outlined in [Manage Docker as a non-root +user](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user) +guide._ + First, create a docker image that will host your kernel. This will require a proper dockerfile. An example can be seen [here](https://github.com/MrMino/dockernel/blob/master/example_dockerfile). @@ -31,7 +38,6 @@ above: docker build --tag my_kernel - < example_dockerfile ``` -_*Note*: Use `sudo` if you run into permission errors._ After that, use Dockernel to install the docker image as a Jupyter kernel: From e69e9fd1f412cbdf8c521a4b96a1713c9c25f96d Mon Sep 17 00:00:00 2001 From: Blazej Michalik Date: Mon, 22 Mar 2021 01:18:35 +0100 Subject: [PATCH 08/17] Remove unnecessary '|| true' from example dockerfile --- example_dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example_dockerfile b/example_dockerfile index b810b9a..fc034da 100644 --- a/example_dockerfile +++ b/example_dockerfile @@ -1,4 +1,4 @@ FROM python:3.7-slim-buster RUN pip install --upgrade pip ipython ipykernel -CMD python -m ipykernel_launcher -f $DOCKERNEL_CONNECTION_FILE || true +CMD python -m ipykernel_launcher -f $DOCKERNEL_CONNECTION_FILE From d65ae2a901c9273342d6584f198fc99c501e6528 Mon Sep 17 00:00:00 2001 From: Blazej Michalik Date: Mon, 22 Mar 2021 02:28:49 +0100 Subject: [PATCH 09/17] Expand dockerfile creation instructions in README --- README.md | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c6c0746..e049de0 100644 --- a/README.md +++ b/README.md @@ -27,10 +27,36 @@ If you run into permission errors with `docker` or `dockernel` - either use user](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user) guide._ +### Creating a Dockernel image + First, create a docker image that will host your kernel. This will require a -proper dockerfile. An example can be seen +proper dockerfile. A full example for IPython kernel can be seen [here](https://github.com/MrMino/dockernel/blob/master/example_dockerfile). +Most kernels take a path to a "connection file" (also called "control file" by +some kernels) as a CLI argument. This file contains all of the information +necessary to start up a kernel, including TCP ports to use, IP address, etc. + +When running your container, Dockernel will supply this file and put it into a +predefined path in the container. This path will be given via an environment +variable visible in the container as `$DOCKERNEL_CONNECTION_FILE`. + +Therefore, in order for the kernel to know the connection settings it should +use, you need to pass the contents of this variable in `CMD` of the container. +For example, for IPython kernel: + +``` +CMD python -m ipykernel_launcher -f $DOCKERNEL_CONNECTION_FILE +``` + +Or for the Rust kernel (Evcxr, see the +[example Rust +dockerfile](https://github.com/MrMino/dockernel/blob/master/example_dockerfile)): + +``` +CMD evcxr_jupyter --control_file $DOCKERNEL_CONNECTION_FILE +``` + To build your image, use `docker build`. E.g. to build the example mentioned above: @@ -38,6 +64,7 @@ above: docker build --tag my_kernel - < example_dockerfile ``` +### Installing your image as a Jupyter Kernel After that, use Dockernel to install the docker image as a Jupyter kernel: From 38aa7ce22547dd207df171e4734d297b473f5901 Mon Sep 17 00:00:00 2001 From: Blazej Michalik Date: Mon, 22 Mar 2021 02:29:08 +0100 Subject: [PATCH 10/17] Add an example dockerfile for Rust --- example_rust_dockerfile | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 example_rust_dockerfile diff --git a/example_rust_dockerfile b/example_rust_dockerfile new file mode 100644 index 0000000..26c2b68 --- /dev/null +++ b/example_rust_dockerfile @@ -0,0 +1,5 @@ +FROM rust:1.50.0-buster + +RUN apt-get update && apt-get install build-essential cmake -y +RUN cargo install evcxr_jupyter +CMD evcxr_jupyter --control_file $DOCKERNEL_CONNECTION_FILE From adc92aa1bd163973d9f900f11008ae284ff7533a Mon Sep 17 00:00:00 2001 From: Blazej Michalik Date: Mon, 22 Mar 2021 02:37:49 +0100 Subject: [PATCH 11/17] Make sure setuptools_scm supplies package version --- pyproject.toml | 1 + setup.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 498d416..6c44890 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,3 +2,4 @@ requires = ["setuptools>=42", "wheel", "setuptools_scm[toml]>=3.4"] [tool.setuptools_scm] +write_to = "dockernel/version.py" diff --git a/setup.py b/setup.py index e02756e..6267b7a 100644 --- a/setup.py +++ b/setup.py @@ -1,3 +1,3 @@ import setuptools -setuptools.setup(use_scm_version=True) +setuptools.setup(use_scm_version={'write_to': 'dockernel/version.py'}) From 790d47e5ef14d691fccba84c69abea7c229612a1 Mon Sep 17 00:00:00 2001 From: Blazej Michalik Date: Mon, 22 Mar 2021 02:44:24 +0100 Subject: [PATCH 12/17] Add a stub version.py --- dockernel/version.py | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 dockernel/version.py diff --git a/dockernel/version.py b/dockernel/version.py new file mode 100644 index 0000000..71ee811 --- /dev/null +++ b/dockernel/version.py @@ -0,0 +1,4 @@ +# This file is written to by setuptools_scm. +# The value supplied here is for development purposes only. + +__version__ = '0.0.0.dev' From d2f46c178cf280a2aa744a6e6e0922fbc467a48b Mon Sep 17 00:00:00 2001 From: Blazej Michalik Date: Mon, 22 Mar 2021 02:51:03 +0100 Subject: [PATCH 13/17] Add DOCKERNEL file to installed kernels --- dockernel/kernelspec.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/dockernel/kernelspec.py b/dockernel/kernelspec.py index 4c184b4..49fd03d 100644 --- a/dockernel/kernelspec.py +++ b/dockernel/kernelspec.py @@ -12,9 +12,12 @@ from enum import Enum from pathlib import Path +from .version import version as dockernel_version + KERNELSPEC_FILENAME = 'kernel.json' KERNELSPEC_STORE_DIRNAME = 'kernels' +DOCKERNEL_VERSIONFILE_FILENAME = 'DOCKERNEL' class InterruptMode(str, Enum): @@ -165,3 +168,18 @@ def install_kernelspec(kernelspec_dir: Path, kernelspec: Kernelspec) -> None: kernelspec_dir.mkdir() kernelspec_file = kernelspec_dir/KERNELSPEC_FILENAME kernelspec_file.write_text(kernelspec.json()) + add_dockernel_versionfile(kernelspec_dir) + + +def add_dockernel_versionfile(kernelspec_dir: Path) -> None: + """Generate DOCKERNEL file under the specified path. + + Creates a text file with the current version of dockernel package + + Parameters + ---------- + kernelspec_dir + Path object to the store where the kernel should be installed. + """ + versionfile_path = kernelspec_dir/DOCKERNEL_VERSIONFILE_FILENAME + versionfile_path.write_text(dockernel_version) From 0a027edd13acec9fdfb728227799d625331f13fe Mon Sep 17 00:00:00 2001 From: Blazej Michalik Date: Mon, 22 Mar 2021 02:57:46 +0100 Subject: [PATCH 14/17] Fix wrong example link in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e049de0..6d158ba 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ CMD python -m ipykernel_launcher -f $DOCKERNEL_CONNECTION_FILE Or for the Rust kernel (Evcxr, see the [example Rust -dockerfile](https://github.com/MrMino/dockernel/blob/master/example_dockerfile)): +dockerfile](https://github.com/MrMino/dockernel/blob/master/example_rust_dockerfile)): ``` CMD evcxr_jupyter --control_file $DOCKERNEL_CONNECTION_FILE From fff610b05cf0430b9a4bbf911860151b81ec8a2f Mon Sep 17 00:00:00 2001 From: Blazej Michalik Date: Mon, 22 Mar 2021 02:58:42 +0100 Subject: [PATCH 15/17] Fix italicisation in README permissions note --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6d158ba..5e42067 100644 --- a/README.md +++ b/README.md @@ -20,12 +20,12 @@ different one. ## Usage -_Note for Linux users: +*Note for Linux users: If you run into permission errors with `docker` or `dockernel` - either use `sudo`, or follow the steps outlined in [Manage Docker as a non-root user](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user) -guide._ +guide.* ### Creating a Dockernel image From a59bf474fb8f7dcae2035d36ab2dc273289ee9cc Mon Sep 17 00:00:00 2001 From: Blazej Michalik Date: Mon, 22 Mar 2021 03:01:13 +0100 Subject: [PATCH 16/17] Make sure DOCKERNEL file ends with a newline --- dockernel/kernelspec.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockernel/kernelspec.py b/dockernel/kernelspec.py index 49fd03d..7016263 100644 --- a/dockernel/kernelspec.py +++ b/dockernel/kernelspec.py @@ -182,4 +182,4 @@ def add_dockernel_versionfile(kernelspec_dir: Path) -> None: Path object to the store where the kernel should be installed. """ versionfile_path = kernelspec_dir/DOCKERNEL_VERSIONFILE_FILENAME - versionfile_path.write_text(dockernel_version) + versionfile_path.write_text(dockernel_version + '\n') From 170ef26b1e223c608f45131dd48edbdd0c3dd0f1 Mon Sep 17 00:00:00 2001 From: Blazej Michalik Date: Tue, 6 Apr 2021 01:30:01 +0200 Subject: [PATCH 17/17] Add 3.9 trove classifier to the package --- setup.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.cfg b/setup.cfg index 7a3001d..34987dd 100644 --- a/setup.cfg +++ b/setup.cfg @@ -23,6 +23,7 @@ classifiers = Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 + Programming Language :: Python :: 3.9 Programming Language :: Python :: Implementation :: CPython [options]