mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-07 10:04:07 +00:00
Merge pull request #4528 from meeseeksmachine/auto-backport-of-pr-4503-on-4.x
Backport PR #4503 on branch 4.x (set root_dir when using singleuser extension)
This commit is contained in:
@@ -483,6 +483,11 @@ class JupyterHubSingleUser(ExtensionApp):
|
||||
cfg.answer_yes = True
|
||||
self.config.FileContentsManager.delete_to_trash = False
|
||||
|
||||
# load Spawner.notebook_dir configuration, if given
|
||||
root_dir = os.getenv("JUPYTERHUB_ROOT_DIR", None)
|
||||
if root_dir:
|
||||
cfg.root_dir = os.path.expanduser(root_dir)
|
||||
|
||||
# load http server config from environment
|
||||
url = urlparse(os.environ['JUPYTERHUB_SERVICE_URL'])
|
||||
if url.port:
|
||||
|
@@ -30,6 +30,7 @@ class JupyterHubTestHandler(JupyterHandler):
|
||||
info = {
|
||||
"current_user": self.current_user,
|
||||
"config": self.app.config,
|
||||
"root_dir": self.contents_manager.root_dir,
|
||||
"disable_user_config": getattr(self.app, "disable_user_config", None),
|
||||
"settings": self.settings,
|
||||
"config_file_paths": self.app.config_file_paths,
|
||||
|
@@ -2,6 +2,7 @@
|
||||
import os
|
||||
import sys
|
||||
from contextlib import nullcontext
|
||||
from pprint import pprint
|
||||
from subprocess import CalledProcessError, check_output
|
||||
from unittest import mock
|
||||
from urllib.parse import urlencode, urlparse
|
||||
@@ -171,9 +172,7 @@ async def test_disable_user_config(request, app, tmpdir, full_spawn):
|
||||
)
|
||||
r.raise_for_status()
|
||||
info = r.json()
|
||||
import pprint
|
||||
|
||||
pprint.pprint(info)
|
||||
pprint(info)
|
||||
assert info['disable_user_config']
|
||||
server_config = info['config']
|
||||
settings = info['settings']
|
||||
@@ -198,6 +197,79 @@ async def test_disable_user_config(request, app, tmpdir, full_spawn):
|
||||
assert_not_in_home(path, key)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("extension", [True, False])
|
||||
@pytest.mark.parametrize("notebook_dir", ["", "~", "~/sub", "ABS"])
|
||||
async def test_notebook_dir(
|
||||
request, app, tmpdir, user, full_spawn, extension, notebook_dir
|
||||
):
|
||||
if extension:
|
||||
try:
|
||||
import jupyter_server # noqa
|
||||
except ImportError:
|
||||
pytest.skip("needs jupyter-server 2")
|
||||
else:
|
||||
if jupyter_server.version_info < (2,):
|
||||
pytest.skip("needs jupyter-server 2")
|
||||
|
||||
token = user.new_api_token(scopes=["access:servers!user"])
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
|
||||
spawner = user.spawner
|
||||
if extension:
|
||||
user.spawner.environment["JUPYTERHUB_SINGLEUSER_EXTENSION"] = "1"
|
||||
else:
|
||||
user.spawner.environment["JUPYTERHUB_SINGLEUSER_EXTENSION"] = "0"
|
||||
|
||||
home_dir = tmpdir.join("home").mkdir()
|
||||
sub_dir = home_dir.join("sub").mkdir()
|
||||
with sub_dir.join("subfile.txt").open("w") as f:
|
||||
f.write("txt\n")
|
||||
abs_dir = tmpdir.join("abs").mkdir()
|
||||
with abs_dir.join("absfile.txt").open("w") as f:
|
||||
f.write("absfile\n")
|
||||
|
||||
if notebook_dir:
|
||||
expected_root_dir = notebook_dir.replace("ABS", str(abs_dir)).replace(
|
||||
"~", str(home_dir)
|
||||
)
|
||||
else:
|
||||
expected_root_dir = str(home_dir)
|
||||
|
||||
spawner.notebook_dir = notebook_dir.replace("ABS", str(abs_dir))
|
||||
|
||||
# home_dir is defined on SimpleSpawner
|
||||
user.spawner.home_dir = home = str(home_dir)
|
||||
spawner.environment["HOME"] = home
|
||||
await user.spawn()
|
||||
await app.proxy.add_user(user)
|
||||
url = public_url(app, user)
|
||||
r = await async_requests.get(
|
||||
url_path_join(public_url(app, user), 'jupyterhub-test-info'), headers=headers
|
||||
)
|
||||
r.raise_for_status()
|
||||
info = r.json()
|
||||
pprint(info)
|
||||
|
||||
assert info["root_dir"] == expected_root_dir
|
||||
# secondary check: make sure it has the intended effect on root_dir
|
||||
r = await async_requests.get(
|
||||
url_path_join(public_url(app, user), 'api/contents/'), headers=headers
|
||||
)
|
||||
r.raise_for_status()
|
||||
root_contents = sorted(item['name'] for item in r.json()['content'])
|
||||
|
||||
# check contents
|
||||
if not notebook_dir or notebook_dir == "~":
|
||||
# use any to avoid counting possible automatically created files in $HOME
|
||||
assert 'sub' in root_contents
|
||||
elif notebook_dir == "ABS":
|
||||
assert 'absfile.txt' in root_contents
|
||||
elif notebook_dir == "~/sub":
|
||||
assert 'subfile.txt' in root_contents
|
||||
else:
|
||||
raise ValueError(f"No contents check for {notebook_dir}")
|
||||
|
||||
|
||||
def test_help_output():
|
||||
out = check_output(
|
||||
[sys.executable, '-m', 'jupyterhub.singleuser', '--help-all']
|
||||
|
Reference in New Issue
Block a user