From ee0105a8a509780c35ee0ba139c8ff3cb0bb8096 Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Sun, 29 Mar 2020 05:57:08 +0200 Subject: [PATCH 1/4] start.sh: JUPYTER_ENV_VARS_TO_UNSET introduced Allow you to define variables to be unset before running the command that start.sh is supposed to start. These variables will still be available in the hooks run before. --- base-notebook/start.sh | 14 ++++++++++++++ base-notebook/test/test_container_options.py | 1 - docs/using/common.md | 2 ++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/base-notebook/start.sh b/base-notebook/start.sh index 4b306b53b6..849de60f82 100755 --- a/base-notebook/start.sh +++ b/base-notebook/start.sh @@ -39,6 +39,18 @@ run-hooks () { echo "${0}: done running hooks in ${1}" } +# A helper function to unset env vars listed in the value of the env var +# JUPYTER_ENV_VARS_TO_UNSET. +unset_explicit_env_vars () { + if [ -n "${JUPYTER_ENV_VARS_TO_UNSET}" ]; then + for env_var_to_unset in $(echo "${JUPYTER_ENV_VARS_TO_UNSET}" | tr ',;:' ' '); do + echo "Unset ${env_var_to_unset} due to JUPYTER_ENV_VARS_TO_UNSET" + unset "${env_var_to_unset}" + done + unset JUPYTER_ENV_VARS_TO_UNSET + fi +} + # NOTE: This hook will run as the user the container was started with! run-hooks /usr/local/bin/start-notebook.d @@ -143,6 +155,7 @@ if [ "$(id -u)" == 0 ] ; then # NOTE: This hook is run as the root user! run-hooks /usr/local/bin/before-notebook.d + unset_explicit_env_vars echo "Running as ${NB_USER}:" "${cmd[@]}" exec sudo --preserve-env --set-home --user "${NB_USER}" \ PATH="${PATH}" \ @@ -199,6 +212,7 @@ else # NOTE: This hook is run as the user we started the container as! run-hooks /usr/local/bin/before-notebook.d + unset_explicit_env_vars echo "Executing the command:" "${cmd[@]}" exec "${cmd[@]}" fi diff --git a/base-notebook/test/test_container_options.py b/base-notebook/test/test_container_options.py index 31e529fa81..9c8b8c9f51 100644 --- a/base-notebook/test/test_container_options.py +++ b/base-notebook/test/test_container_options.py @@ -240,7 +240,6 @@ def test_container_not_delete_bind_mount(container, tmp_path): assert len(list(tmp_path.iterdir())) == 1 -@pytest.mark.skip(reason="not yet implemented; TODO: cherry-pick b44b7ab") def test_jupyter_env_vars_to_unset_as_root(container): """Environment variables names listed in JUPYTER_ENV_VARS_TO_UNSET should be unset in the final environment.""" diff --git a/docs/using/common.md b/docs/using/common.md index b42ecb87b6..93a9a78003 100644 --- a/docs/using/common.md +++ b/docs/using/common.md @@ -78,6 +78,8 @@ You do so by passing arguments to the `docker run` command. **You must grant the within-container notebook user or group (`NB_UID` or `NB_GID`) write access to the host directory (e.g., `sudo chown 1000 /some/host/folder/for/work`).** - `--user 5000 --group-add users` - Launches the container with a specific user ID and adds that user to the `users` group so that it can modify files in the default home directory and `/opt/conda`. You can use these arguments as alternatives to setting `${NB_UID}` and `${NB_GID}`. +- `-e JUPYTER_ENV_VARS_TO_UNSET=ADMIN_SECRET_1,ADMIN_SECRET_2` - Unsets specified environment variables in the default startup script. + The variables are unset after the hooks have executed but before the command provided to the startup script runs. ## Startup Hooks From d4759372ce818111a683bd1fb3f1f7a7ecf1414d Mon Sep 17 00:00:00 2001 From: Ayaz Salikhov Date: Fri, 12 Nov 2021 19:43:00 +0300 Subject: [PATCH 2/4] Only allow comma separation --- base-notebook/start.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base-notebook/start.sh b/base-notebook/start.sh index 849de60f82..6ab6d223be 100755 --- a/base-notebook/start.sh +++ b/base-notebook/start.sh @@ -43,7 +43,7 @@ run-hooks () { # JUPYTER_ENV_VARS_TO_UNSET. unset_explicit_env_vars () { if [ -n "${JUPYTER_ENV_VARS_TO_UNSET}" ]; then - for env_var_to_unset in $(echo "${JUPYTER_ENV_VARS_TO_UNSET}" | tr ',;:' ' '); do + for env_var_to_unset in $(echo "${JUPYTER_ENV_VARS_TO_UNSET}" | tr ',' ' '); do echo "Unset ${env_var_to_unset} due to JUPYTER_ENV_VARS_TO_UNSET" unset "${env_var_to_unset}" done From b6ab91a6062deae17b8f445686bf470f99579ccd Mon Sep 17 00:00:00 2001 From: Ayaz Salikhov Date: Fri, 12 Nov 2021 19:45:28 +0300 Subject: [PATCH 3/4] Fix an example --- base-notebook/test/test_container_options.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base-notebook/test/test_container_options.py b/base-notebook/test/test_container_options.py index 9c8b8c9f51..ca8b61feb9 100644 --- a/base-notebook/test/test_container_options.py +++ b/base-notebook/test/test_container_options.py @@ -249,14 +249,14 @@ def test_jupyter_env_vars_to_unset_as_root(container): environment=[ "JUPYTER_ENV_VARS_TO_UNSET=SECRET_ANIMAL,UNUSED_ENV,SECRET_FRUIT", "FRUIT=bananas", - "SECRET_FRUIT=mango", "SECRET_ANIMAL=cats", + "SECRET_FRUIT=mango", ], command=[ "start.sh", "bash", "-c", - "echo I like $FRUIT and ${SECRET_FRUIT:-stuff}, and love ${SECRET_LOVE:-to keep secrets}!", + "echo I like $FRUIT and ${SECRET_FRUIT:-stuff}, and love ${SECRET_ANIMAL:-to keep secrets}!", ], ) rv = c.wait(timeout=10) From 058229dc3a871fd17ee25427930fb3eea0fd56da Mon Sep 17 00:00:00 2001 From: Ayaz Salikhov Date: Mon, 15 Nov 2021 16:11:58 +0300 Subject: [PATCH 4/4] Add non-root test --- base-notebook/test/test_container_options.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/base-notebook/test/test_container_options.py b/base-notebook/test/test_container_options.py index ca8b61feb9..8e49ee4149 100644 --- a/base-notebook/test/test_container_options.py +++ b/base-notebook/test/test_container_options.py @@ -240,12 +240,13 @@ def test_container_not_delete_bind_mount(container, tmp_path): assert len(list(tmp_path.iterdir())) == 1 -def test_jupyter_env_vars_to_unset_as_root(container): +@pytest.mark.parametrize("enable_root", [False, True]) +def test_jupyter_env_vars_to_unset_as_root(container, enable_root): """Environment variables names listed in JUPYTER_ENV_VARS_TO_UNSET should be unset in the final environment.""" + root_args = {"user": "root"} if enable_root else {} c = container.run( tty=True, - user="root", environment=[ "JUPYTER_ENV_VARS_TO_UNSET=SECRET_ANIMAL,UNUSED_ENV,SECRET_FRUIT", "FRUIT=bananas", @@ -258,6 +259,7 @@ def test_jupyter_env_vars_to_unset_as_root(container): "-c", "echo I like $FRUIT and ${SECRET_FRUIT:-stuff}, and love ${SECRET_ANIMAL:-to keep secrets}!", ], + **root_args, ) rv = c.wait(timeout=10) assert rv == 0 or rv["StatusCode"] == 0