From 2bf23f0b28a3b55520773704cb71c5cb23f9c3fc Mon Sep 17 00:00:00 2001 From: Min RK Date: Tue, 28 Aug 2018 14:00:43 +0200 Subject: [PATCH 1/8] put config in a single `config` directory instead of top-level files - ensure directory is private - both tljh and jupyterhub config go in there - move old config.yaml to new location at install time --- tljh/config.py | 6 ++++- tljh/installer.py | 49 +++++++++++++++++++++++++++++++++------ tljh/jupyterhub_config.py | 4 ++-- 3 files changed, 49 insertions(+), 10 deletions(-) diff --git a/tljh/config.py b/tljh/config.py index 7f6e3b4..a9855d0 100644 --- a/tljh/config.py +++ b/tljh/config.py @@ -27,7 +27,11 @@ INSTALL_PREFIX = os.environ.get('TLJH_INSTALL_PREFIX', '/opt/tljh') HUB_ENV_PREFIX = os.path.join(INSTALL_PREFIX, 'hub') USER_ENV_PREFIX = os.path.join(INSTALL_PREFIX, 'user') STATE_DIR = os.path.join(INSTALL_PREFIX, 'state') -CONFIG_FILE = os.path.join(INSTALL_PREFIX, 'config.yaml') +CONFIG_DIR = os.path.join(INSTALL_PREFIX, 'config') +CONFIG_FILE = os.path.join(CONFIG_DIR, 'config.yaml') + +# deprecated config file location +OLD_CONFIG_FILE = os.path.join(INSTALL_PREFIX, 'config.yaml') def set_item_in_config(config, property_path, value): diff --git a/tljh/installer.py b/tljh/installer.py index 6d5009a..f27af3e 100644 --- a/tljh/installer.py +++ b/tljh/installer.py @@ -1,19 +1,31 @@ +"""Installation logic for TLJH""" + import argparse +from datetime import date +import itertools +import logging import os import secrets +import shutil import subprocess -import itertools import sys import time -import logging from urllib.error import HTTPError from urllib.request import urlopen, URLError -import pluggy +import pluggy from ruamel.yaml import YAML from tljh import conda, systemd, traefik, user, apt, hooks -from tljh.config import INSTALL_PREFIX, HUB_ENV_PREFIX, USER_ENV_PREFIX, STATE_DIR, CONFIG_FILE +from tljh.config import ( + CONFIG_DIR, + CONFIG_FILE, + HUB_ENV_PREFIX, + INSTALL_PREFIX, + OLD_CONFIG_FILE, + STATE_DIR, + USER_ENV_PREFIX, +) HERE = os.path.abspath(os.path.dirname(__file__)) @@ -254,7 +266,7 @@ def ensure_admins(admins): if not admins: return logger.info("Setting up admin users") - config_path = os.path.join(INSTALL_PREFIX, 'config.yaml') + config_path = CONFIG_FILE if os.path.exists(config_path): with open(config_path, 'r') as f: config = rt_yaml.load(f) @@ -339,6 +351,7 @@ def setup_plugins(plugins): return pm + def run_plugin_actions(plugin_manager, plugins): """ Run installer hooks defined in plugins @@ -373,6 +386,29 @@ def ensure_config_yaml(plugin_manager): """ Ensure we have a config.yaml present """ + # ensure config dir exists and is private + for path in [CONFIG_DIR, os.path.join(CONFIG_DIR, 'jupyterhub_config.d')]: + os.makedirs(path, mode=0o700, exist_ok=True) + + # handle old TLJH_DIR/config.yaml location + if os.path.exists(OLD_CONFIG_FILE): + if os.path.exists(CONFIG_FILE): + # new config file already created! still move the config, + # but avoid collision + timestamp = date.today().isoformat() + dest = dest_base = f"{CONFIG_FILE}.old.{timestamp}" + i = 0 + while os.path.exists(dest): + # avoid collisions + dest = dest_base + f".{i}" + i += 1 + logger.warning(f"Found config in both old ({OLD_CONFIG_FILE}) and new ({CONFIG_FILE}).") + logger.warning(f"Moving {OLD_CONFIG_FILE} to {dest} to avoid clobbering. Its contents will be ignored.") + else: + logger.warning(f"Moving old config file to new location {OLD_CONFIG_FILE} -> {CONFIG_FILE}") + dest = CONFIG_FILE + shutil.move(OLD_CONFIG_FILE, dest) + if os.path.exists(CONFIG_FILE): with open(CONFIG_FILE, 'r') as f: config = rt_yaml.load(f) @@ -407,8 +443,8 @@ def main(): pm = setup_plugins(args.plugin) + ensure_config_yaml(pm) ensure_admins(args.admin) - ensure_usergroups() ensure_user_environment(args.user_requirements_txt_url) @@ -416,7 +452,6 @@ def main(): ensure_node() ensure_jupyterhub_package(HUB_ENV_PREFIX) ensure_chp_package(HUB_ENV_PREFIX) - ensure_config_yaml(pm) ensure_jupyterlab_extensions() ensure_jupyterhub_service(HUB_ENV_PREFIX) ensure_jupyterhub_running() diff --git a/tljh/jupyterhub_config.py b/tljh/jupyterhub_config.py index 4abb891..994e506 100644 --- a/tljh/jupyterhub_config.py +++ b/tljh/jupyterhub_config.py @@ -8,7 +8,7 @@ from glob import glob from systemdspawner import SystemdSpawner from tljh import user, configurer -from tljh.config import INSTALL_PREFIX, USER_ENV_PREFIX +from tljh.config import INSTALL_PREFIX, USER_ENV_PREFIX, CONFIG_DIR class CustomSpawner(SystemdSpawner): @@ -50,6 +50,6 @@ configurer.apply_config(config_overrides, c) # Load arbitrary .py config files if they exist. # This is our escape hatch -extra_configs = sorted(glob(os.path.join(INSTALL_PREFIX, 'jupyterhub_config.d', '*.py'))) +extra_configs = sorted(glob(os.path.join(CONFIG_DIR, 'jupyterhub_config.d', '*.py'))) for ec in extra_configs: load_subconfig(ec) From 4b79993ea074032a29a86886162776f9d361cf5d Mon Sep 17 00:00:00 2001 From: Min RK Date: Tue, 28 Aug 2018 14:16:09 +0200 Subject: [PATCH 2/8] test config dir setup including upgrading old config files --- tests/test_installer.py | 49 ++++++++++++++++++++++++++++++++++++++++- tljh/installer.py | 2 +- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/tests/test_installer.py b/tests/test_installer.py index b8a7834..f845209 100644 --- a/tests/test_installer.py +++ b/tests/test_installer.py @@ -1,10 +1,57 @@ """ Unit test functions in installer.py """ -from tljh import installer import os +from datetime import date + +from tljh import installer + def test_ensure_node(): installer.ensure_node() assert os.path.exists('/usr/bin/node') + + +def test_ensure_config_yaml(tljh_dir): + pm = installer.setup_plugins() + installer.ensure_config_yaml(pm) + assert os.path.exists(installer.CONFIG_FILE) + assert os.path.isdir(installer.CONFIG_DIR) + assert os.path.isdir(os.path.join(installer.CONFIG_DIR, 'jupyterhub_config.d')) + assert not os.path.exists(installer.OLD_CONFIG_FILE) + + # run again, with old config in the way and no new config + upgraded_config = 'old: config\n' + with open(installer.OLD_CONFIG_FILE, 'w') as f: + f.write(upgraded_config) + os.remove(installer.CONFIG_FILE) + installer.ensure_config_yaml(pm) + assert os.path.exists(installer.CONFIG_FILE) + assert not os.path.exists(installer.OLD_CONFIG_FILE) + with open(installer.CONFIG_FILE) as f: + assert f.read() == upgraded_config + + # run again, this time with both old and new config + duplicate_config = 'dupe: config\n' + with open(installer.OLD_CONFIG_FILE, 'w') as f: + f.write(duplicate_config) + installer.ensure_config_yaml(pm) + assert os.path.exists(installer.CONFIG_FILE) + assert not os.path.exists(installer.OLD_CONFIG_FILE) + # didn't clobber config: + with open(installer.CONFIG_FILE) as f: + assert f.read() == upgraded_config + + # preserved old config + backup_config = installer.CONFIG_FILE + f".old.{date.today().isoformat()}" + assert os.path.exists(backup_config) + with open(backup_config) as f: + assert f.read() == duplicate_config + + + + + + + diff --git a/tljh/installer.py b/tljh/installer.py index f27af3e..70049a8 100644 --- a/tljh/installer.py +++ b/tljh/installer.py @@ -336,7 +336,7 @@ def ensure_symlinks(prefix): os.symlink(tljh_config_src, tljh_config_dest) -def setup_plugins(plugins): +def setup_plugins(plugins=None): """ Install plugins & setup a pluginmanager """ From 01a1226d5185a02a2b4c9d15ee261adbb53be161 Mon Sep 17 00:00:00 2001 From: Min RK Date: Tue, 28 Aug 2018 14:23:44 +0200 Subject: [PATCH 3/8] update config path in docs --- docs/contributing/dev-setup.rst | 4 ++-- docs/howto/env/notebook-interfaces.rst | 2 +- docs/topic/escape-hatch.rst | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/contributing/dev-setup.rst b/docs/contributing/dev-setup.rst index 2cbf5ae..b80e9ad 100644 --- a/docs/contributing/dev-setup.rst +++ b/docs/contributing/dev-setup.rst @@ -59,8 +59,8 @@ The easiest & safest way to develop & test TLJH is with `Docker Date: Wed, 29 Aug 2018 09:45:15 +0200 Subject: [PATCH 4/8] ensure config_dir exists in unittests --- tests/conftest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/conftest.py b/tests/conftest.py index b48fd4a..77262e1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -21,4 +21,5 @@ def tljh_dir(tmpdir): reload(mod) assert tljh.config.INSTALL_PREFIX == tljh_dir os.makedirs(tljh.config.STATE_DIR) + os.makedirs(tljh.config.CONFIG_DIR) yield tljh_dir From 204442d370ebbf4cc0c750db8967cdcd72f0c98a Mon Sep 17 00:00:00 2001 From: Min RK Date: Wed, 29 Aug 2018 16:02:41 +0200 Subject: [PATCH 5/8] fix config.yaml path in jupyterhub_config.py --- tljh/jupyterhub_config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tljh/jupyterhub_config.py b/tljh/jupyterhub_config.py index 994e506..97c76ce 100644 --- a/tljh/jupyterhub_config.py +++ b/tljh/jupyterhub_config.py @@ -40,7 +40,7 @@ c.SystemdSpawner.default_shell = '/bin/bash' # Drop the '-singleuser' suffix present in the default template c.SystemdSpawner.unit_name_template = 'jupyter-{USERNAME}' -config_overrides_path = os.path.join(INSTALL_PREFIX, 'config.yaml') +config_overrides_path = os.path.join(CONFIG_DIR, 'config.yaml') if os.path.exists(config_overrides_path): with open(config_overrides_path) as f: config_overrides = yaml.safe_load(f) From 37ad207be9d448f9b2d2434f197b415b34191bcd Mon Sep 17 00:00:00 2001 From: Min RK Date: Fri, 31 Aug 2018 12:00:42 +0200 Subject: [PATCH 6/8] centralize logging initialization so it can be shared across modules --- tljh/config.py | 3 +++ tljh/installer.py | 15 +++------------ tljh/log.py | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+), 12 deletions(-) create mode 100644 tljh/log.py diff --git a/tljh/config.py b/tljh/config.py index a9855d0..8c3c050 100644 --- a/tljh/config.py +++ b/tljh/config.py @@ -225,6 +225,9 @@ def main(argv=None): if argv is None: argv = sys.argv[1:] + from .log import init_logging + init_logging() + argparser = argparse.ArgumentParser() argparser.add_argument( '--config-path', diff --git a/tljh/installer.py b/tljh/installer.py index 70049a8..d45b51e 100644 --- a/tljh/installer.py +++ b/tljh/installer.py @@ -31,20 +31,8 @@ HERE = os.path.abspath(os.path.dirname(__file__)) rt_yaml = YAML() -# Set up logging to print to a file and to stderr logger = logging.getLogger(__name__) -os.makedirs(INSTALL_PREFIX, exist_ok=True) -file_logger = logging.FileHandler(os.path.join(INSTALL_PREFIX, 'installer.log')) -file_logger.setFormatter(logging.Formatter('%(asctime)s %(message)s')) -logger.addHandler(file_logger) - -stderr_logger = logging.StreamHandler() -stderr_logger.setFormatter(logging.Formatter('%(message)s')) -logger.addHandler(stderr_logger) -logger.setLevel(logging.INFO) - - def ensure_node(): """ Ensure nodejs from nodesource is installed @@ -423,6 +411,9 @@ def ensure_config_yaml(plugin_manager): def main(): + from .log import init_logging + init_logging() + argparser = argparse.ArgumentParser() argparser.add_argument( '--admin', diff --git a/tljh/log.py b/tljh/log.py new file mode 100644 index 0000000..f626c96 --- /dev/null +++ b/tljh/log.py @@ -0,0 +1,19 @@ +"""Setup tljh logging""" +import os +import logging + +from .config import INSTALL_PREFIX + + +def init_logging(): + """Setup default tljh logger""" + logger = logging.getLogger("tljh") + os.makedirs(INSTALL_PREFIX, exist_ok=True) + file_logger = logging.FileHandler(os.path.join(INSTALL_PREFIX, "installer.log")) + file_logger.setFormatter(logging.Formatter("%(asctime)s %(message)s")) + logger.addHandler(file_logger) + + stderr_logger = logging.StreamHandler() + stderr_logger.setFormatter(logging.Formatter("%(message)s")) + logger.addHandler(stderr_logger) + logger.setLevel(logging.INFO) From 5df106fa82df1f0005d5aeaca48b45f7c71dc690 Mon Sep 17 00:00:00 2001 From: Min RK Date: Fri, 31 Aug 2018 12:17:16 +0200 Subject: [PATCH 7/8] move config migration to its own file --- tests/test_installer.py | 40 ++---------------------- tests/test_migrator.py | 57 ++++++++++++++++++++++++++++++++++ tljh/config.py | 3 -- tljh/installer.py | 33 +++++++------------- tljh/migrator.py | 69 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 139 insertions(+), 63 deletions(-) create mode 100644 tests/test_migrator.py create mode 100644 tljh/migrator.py diff --git a/tests/test_installer.py b/tests/test_installer.py index f845209..d97f01b 100644 --- a/tests/test_installer.py +++ b/tests/test_installer.py @@ -2,12 +2,10 @@ Unit test functions in installer.py """ import os -from datetime import date from tljh import installer - def test_ensure_node(): installer.ensure_node() assert os.path.exists('/usr/bin/node') @@ -19,39 +17,5 @@ def test_ensure_config_yaml(tljh_dir): assert os.path.exists(installer.CONFIG_FILE) assert os.path.isdir(installer.CONFIG_DIR) assert os.path.isdir(os.path.join(installer.CONFIG_DIR, 'jupyterhub_config.d')) - assert not os.path.exists(installer.OLD_CONFIG_FILE) - - # run again, with old config in the way and no new config - upgraded_config = 'old: config\n' - with open(installer.OLD_CONFIG_FILE, 'w') as f: - f.write(upgraded_config) - os.remove(installer.CONFIG_FILE) - installer.ensure_config_yaml(pm) - assert os.path.exists(installer.CONFIG_FILE) - assert not os.path.exists(installer.OLD_CONFIG_FILE) - with open(installer.CONFIG_FILE) as f: - assert f.read() == upgraded_config - - # run again, this time with both old and new config - duplicate_config = 'dupe: config\n' - with open(installer.OLD_CONFIG_FILE, 'w') as f: - f.write(duplicate_config) - installer.ensure_config_yaml(pm) - assert os.path.exists(installer.CONFIG_FILE) - assert not os.path.exists(installer.OLD_CONFIG_FILE) - # didn't clobber config: - with open(installer.CONFIG_FILE) as f: - assert f.read() == upgraded_config - - # preserved old config - backup_config = installer.CONFIG_FILE + f".old.{date.today().isoformat()}" - assert os.path.exists(backup_config) - with open(backup_config) as f: - assert f.read() == duplicate_config - - - - - - - + # verify that old config doesn't exist + assert not os.path.exists(os.path.join(tljh_dir, 'config.yaml')) diff --git a/tests/test_migrator.py b/tests/test_migrator.py new file mode 100644 index 0000000..24e67a8 --- /dev/null +++ b/tests/test_migrator.py @@ -0,0 +1,57 @@ +""" +Unit test functions in installer.py +""" +import os +from datetime import date + +from tljh import migrator, config + + +def test_migrate_config(tljh_dir): + CONFIG_FILE = config.CONFIG_FILE + CONFIG_DIR = config.CONFIG_DIR + OLD_CONFIG_FILE = os.path.join(tljh_dir, "config.yaml") + OLD_CONFIG_D = os.path.join(tljh_dir, "jupyterhub_config.d") + CONFIG_D = os.path.join(config.CONFIG_DIR, "jupyterhub_config.d") + old_config_py = os.path.join(OLD_CONFIG_D, "upgrade.py") + new_config_py = os.path.join(CONFIG_D, "upgrade.py") + + # initial condition: nothing exists + assert not os.path.exists(CONFIG_FILE) + assert not os.path.exists(OLD_CONFIG_FILE) + assert os.path.isdir(CONFIG_DIR) + + # run migration with old config and no new config + upgraded_config = "old: config\n" + with open(OLD_CONFIG_FILE, "w") as f: + f.write(upgraded_config) + os.makedirs(OLD_CONFIG_D, exist_ok=True) + with open(old_config_py, "w") as f: + f.write("c.JupyterHub.log_level = 10") + + migrator.migrate_config_files() + assert os.path.exists(CONFIG_FILE) + assert not os.path.exists(OLD_CONFIG_FILE) + with open(CONFIG_FILE) as f: + assert f.read() == upgraded_config + assert os.path.exists(new_config_py) + assert not os.path.exists(OLD_CONFIG_D) + + # run again, this time with both old and new config + duplicate_config = "dupe: config\n" + with open(OLD_CONFIG_FILE, "w") as f: + f.write(duplicate_config) + migrator.migrate_config_files() + assert os.path.exists(CONFIG_FILE) + assert not os.path.exists(OLD_CONFIG_FILE) + # didn't clobber config: + with open(CONFIG_FILE) as f: + assert f.read() == upgraded_config + + # preserved old config + backup_config = CONFIG_FILE + f".old.{date.today().isoformat()}" + assert os.path.exists(backup_config) + with open(backup_config) as f: + assert f.read() == duplicate_config + + # migrate jupyterhub_con diff --git a/tljh/config.py b/tljh/config.py index 8c3c050..a09bda1 100644 --- a/tljh/config.py +++ b/tljh/config.py @@ -30,9 +30,6 @@ STATE_DIR = os.path.join(INSTALL_PREFIX, 'state') CONFIG_DIR = os.path.join(INSTALL_PREFIX, 'config') CONFIG_FILE = os.path.join(CONFIG_DIR, 'config.yaml') -# deprecated config file location -OLD_CONFIG_FILE = os.path.join(INSTALL_PREFIX, 'config.yaml') - def set_item_in_config(config, property_path, value): """ diff --git a/tljh/installer.py b/tljh/installer.py index d45b51e..2fa8c0c 100644 --- a/tljh/installer.py +++ b/tljh/installer.py @@ -1,12 +1,10 @@ """Installation logic for TLJH""" import argparse -from datetime import date import itertools import logging import os import secrets -import shutil import subprocess import sys import time @@ -16,13 +14,21 @@ from urllib.request import urlopen, URLError import pluggy from ruamel.yaml import YAML -from tljh import conda, systemd, traefik, user, apt, hooks +from tljh import ( + apt, + conda, + hooks, + migrator, + systemd, + traefik, + user, +) + from tljh.config import ( CONFIG_DIR, CONFIG_FILE, HUB_ENV_PREFIX, INSTALL_PREFIX, - OLD_CONFIG_FILE, STATE_DIR, USER_ENV_PREFIX, ) @@ -378,24 +384,7 @@ def ensure_config_yaml(plugin_manager): for path in [CONFIG_DIR, os.path.join(CONFIG_DIR, 'jupyterhub_config.d')]: os.makedirs(path, mode=0o700, exist_ok=True) - # handle old TLJH_DIR/config.yaml location - if os.path.exists(OLD_CONFIG_FILE): - if os.path.exists(CONFIG_FILE): - # new config file already created! still move the config, - # but avoid collision - timestamp = date.today().isoformat() - dest = dest_base = f"{CONFIG_FILE}.old.{timestamp}" - i = 0 - while os.path.exists(dest): - # avoid collisions - dest = dest_base + f".{i}" - i += 1 - logger.warning(f"Found config in both old ({OLD_CONFIG_FILE}) and new ({CONFIG_FILE}).") - logger.warning(f"Moving {OLD_CONFIG_FILE} to {dest} to avoid clobbering. Its contents will be ignored.") - else: - logger.warning(f"Moving old config file to new location {OLD_CONFIG_FILE} -> {CONFIG_FILE}") - dest = CONFIG_FILE - shutil.move(OLD_CONFIG_FILE, dest) + migrator.migrate_config_files() if os.path.exists(CONFIG_FILE): with open(CONFIG_FILE, 'r') as f: diff --git a/tljh/migrator.py b/tljh/migrator.py new file mode 100644 index 0000000..a301c93 --- /dev/null +++ b/tljh/migrator.py @@ -0,0 +1,69 @@ +"""Migration utilities for upgrading tljh""" + +import os +from datetime import date +import logging +import shutil + +from tljh.config import ( + CONFIG_DIR, + CONFIG_FILE, + INSTALL_PREFIX, +) + + +logger = logging.getLogger(__name__) + + +def migrate_file(old_path, new_path): + """Migrate one file from an old location to a new one + + avoids collisions if the new file exists + """ + if not os.path.exists(old_path): + return + if os.path.exists(new_path): + # new config file already created! still move the config, + # but avoid collision + timestamp = date.today().isoformat() + dest = dest_base = f"{new_path}.old.{timestamp}" + i = 0 + while os.path.exists(dest): + # avoid collisions + dest = dest_base + f".{i}" + i += 1 + logger.warning(f"Found file in both old ({old_path}) and new ({new_path}).") + logger.warning( + f"Moving {old_path} to {dest} to avoid clobbering. Its contents will be ignored." + ) + else: + dest = new_path + shutil.move(old_path, dest) + + +def migrate_directory(old_dir, new_dir): + """Migrate a directory to a new location""" + if not os.path.exists(old_dir): + return + if os.path.exists(new_dir): + # both dirs exist + for f in os.listdir(old_dir): + src = os.path.join(old_dir, f) + dest = os.path.join(new_dir, f) + if os.path.isdir(src): + migrate_directory(src, dest) + else: + migrate_file(src, dest) + else: + logger.warning(f"Moving directory to new location {old_dir} -> {new_dir}") + shutil.move(old_dir, new_dir) + + +def migrate_config_files(): + """Migrate config files to their new locations""" + # handle old TLJH_DIR/config.yaml location + migrate_file(os.path.join(INSTALL_PREFIX, "config.yaml"), CONFIG_FILE) + migrate_directory( + os.path.join(INSTALL_PREFIX, "jupyterhub_config.d"), + os.path.join(CONFIG_DIR, "jupyterhub_config.d"), + ) From 626e492e0ffdc258dd72b206541a94c1d5a0c2a6 Mon Sep 17 00:00:00 2001 From: Min RK Date: Fri, 31 Aug 2018 12:25:30 +0200 Subject: [PATCH 8/8] use variables in test_simplest_plugin avoids updating hardcoded paths when they change --- integration-tests/test_simplest_plugin.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/integration-tests/test_simplest_plugin.py b/integration-tests/test_simplest_plugin.py index c35de5d..29b4fab 100644 --- a/integration-tests/test_simplest_plugin.py +++ b/integration-tests/test_simplest_plugin.py @@ -4,6 +4,7 @@ Test simplest plugin from ruamel.yaml import YAML import os import subprocess +from tljh.config import CONFIG_FILE, USER_ENV_PREFIX yaml = YAML(typ='rt') @@ -20,7 +21,7 @@ def test_pip_packages(): Test extra user pip packages are installed """ subprocess.check_call([ - '/opt/tljh/user/bin/python3', + f'{USER_ENV_PREFIX}/bin/python3', '-c', 'import django' ]) @@ -31,7 +32,7 @@ def test_conda_packages(): Test extra user conda packages are installed """ subprocess.check_call([ - '/opt/tljh/user/bin/python3', + f'{USER_ENV_PREFIX}/bin/python3', '-c', 'import hypothesis' ]) @@ -41,7 +42,7 @@ def test_config_hook(): """ Check config changes are present """ - with open('/opt/tljh/config.yaml') as f: + with open(CONFIG_FILE) as f: data = yaml.load(f) - assert data['simplest_plugin']['present'] \ No newline at end of file + assert data['simplest_plugin']['present']