Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid requiring jupyter_config.py in to be in uiserver subdirectory #594

Draft
wants to merge 1 commit into
base: 1.5.x
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes.d/594.fix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Avoid requiring jupyter_config.py in to be in uiserver subdirectory when using CYLC_SITE_CONF_PATH
3 changes: 2 additions & 1 deletion cylc/uiserver/config_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
)

# base configuration - always used
DEFAULT_CONF_PATH: Path = Path(uis_pkg).parent / 'jupyter_config.py'
CONF_FILE_NAME = 'jupyter_config.py'
DEFAULT_CONF_PATH: Path = Path(uis_pkg).parent / CONF_FILE_NAME
UISERVER_DIR = 'uiserver'
# UIS configuration dirs
SITE_CONF_ROOT: Path = Path(
Expand Down
26 changes: 21 additions & 5 deletions cylc/uiserver/jupyterhub_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
from pathlib import Path

from cylc.uiserver.config_util import (
CONF_FILE_NAME,
DEFAULT_CONF_PATH,
UISERVER_DIR,
USER_CONF_ROOT,
SITE_CONF_ROOT,
get_conf_dir_hierarchy
Expand All @@ -46,10 +46,8 @@ def _load(path):
def load() -> None:
"""Load the relevant UIS/Hub configuration files."""
if os.getenv('CYLC_SITE_CONF_PATH'):
site_conf_path: Path = Path(
os.environ['CYLC_SITE_CONF_PATH'],
UISERVER_DIR
)
site_conf_path: Path = check_cylc_site_conf_path(
Path(os.environ['CYLC_SITE_CONF_PATH']))
else:
site_conf_path = SITE_CONF_ROOT
base_config_paths = [site_conf_path, USER_CONF_ROOT]
Expand All @@ -61,6 +59,24 @@ def load() -> None:
_load(Path(path))


def check_cylc_site_conf_path(path_: Path) -> Path:
"""Check path set by CYLC_SITE_CONF_PATH

1. Path exists and has a file.
2. File is readable.
"""
conf_file_path = (path_ / CONF_FILE_NAME)
if not conf_file_path.is_file():
LOG.warning(
f'Config path {path_} set by'
' "CYLC_SITE_CONF_PATH" does not exist or.'
' does not have a jupyter_config.py file.')
elif not os.access(conf_file_path, os.R_OK):
LOG.error(f'Unable to read config file at {path_}')
return SITE_CONF_ROOT
return path_


hub_version = os.environ.get('CYLC_HUB_VERSION')
if hub_version:
# auto-load the config (jupyterhub requirement)
Expand Down
4 changes: 2 additions & 2 deletions cylc/uiserver/tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ def test_cylc_site_conf_path(clear_env, capload, monkeypatch):
load()
assert capload == [
SYS_CONF,
Path('elephant/uiserver/jupyter_config.py'),
Path('elephant/uiserver/0/jupyter_config.py'),
Path('elephant/jupyter_config.py'),
Path('elephant/0/jupyter_config.py'),
Path(USER_CONF / 'jupyter_config.py'),
Path(USER_CONF / '0/jupyter_config.py')
]
Expand Down
39 changes: 39 additions & 0 deletions cylc/uiserver/tests/test_jupyterhub_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright (C) NIWA & British Crown (Met Office) & Contributors.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Tests for jupyterhub_config module."""

from cylc.uiserver.jupyterhub_config import check_cylc_site_conf_path
from cylc.uiserver.config_util import CONF_FILE_NAME, SITE_CONF_ROOT


def test_cylc_site_conf_path_ok(tmp_path, caplog):
"""Method passes valid file without comment"""
(tmp_path / CONF_FILE_NAME).touch()
assert check_cylc_site_conf_path(tmp_path) == tmp_path
assert caplog.messages == []


def test_cylc_site_conf_path_unreadable(tmp_path, caplog):
"""Method logs error because file exists but is unreadable."""
(tmp_path / CONF_FILE_NAME).touch()
(tmp_path / CONF_FILE_NAME).chmod(0)
assert check_cylc_site_conf_path(tmp_path) == SITE_CONF_ROOT
assert caplog.messages[0].startswith('Unable to read config file at')


def test_cylc_site_conf_path_empty(tmp_path, caplog):
"""Method logs error because file does not exist."""
assert check_cylc_site_conf_path(tmp_path) == tmp_path
assert 'does not exist' in caplog.messages[0]
Loading