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
This commit is contained in:
Min RK
2018-08-28 14:00:43 +02:00
parent 49a8a6f8f0
commit 2bf23f0b28
3 changed files with 49 additions and 10 deletions

View File

@@ -27,7 +27,11 @@ INSTALL_PREFIX = os.environ.get('TLJH_INSTALL_PREFIX', '/opt/tljh')
HUB_ENV_PREFIX = os.path.join(INSTALL_PREFIX, 'hub') HUB_ENV_PREFIX = os.path.join(INSTALL_PREFIX, 'hub')
USER_ENV_PREFIX = os.path.join(INSTALL_PREFIX, 'user') USER_ENV_PREFIX = os.path.join(INSTALL_PREFIX, 'user')
STATE_DIR = os.path.join(INSTALL_PREFIX, 'state') 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): def set_item_in_config(config, property_path, value):

View File

@@ -1,19 +1,31 @@
"""Installation logic for TLJH"""
import argparse import argparse
from datetime import date
import itertools
import logging
import os import os
import secrets import secrets
import shutil
import subprocess import subprocess
import itertools
import sys import sys
import time import time
import logging
from urllib.error import HTTPError from urllib.error import HTTPError
from urllib.request import urlopen, URLError from urllib.request import urlopen, URLError
import pluggy
import pluggy
from ruamel.yaml import YAML from ruamel.yaml import YAML
from tljh import conda, systemd, traefik, user, apt, hooks 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__)) HERE = os.path.abspath(os.path.dirname(__file__))
@@ -254,7 +266,7 @@ def ensure_admins(admins):
if not admins: if not admins:
return return
logger.info("Setting up admin users") 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): if os.path.exists(config_path):
with open(config_path, 'r') as f: with open(config_path, 'r') as f:
config = rt_yaml.load(f) config = rt_yaml.load(f)
@@ -339,6 +351,7 @@ def setup_plugins(plugins):
return pm return pm
def run_plugin_actions(plugin_manager, plugins): def run_plugin_actions(plugin_manager, plugins):
""" """
Run installer hooks defined in 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 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): if os.path.exists(CONFIG_FILE):
with open(CONFIG_FILE, 'r') as f: with open(CONFIG_FILE, 'r') as f:
config = rt_yaml.load(f) config = rt_yaml.load(f)
@@ -407,8 +443,8 @@ def main():
pm = setup_plugins(args.plugin) pm = setup_plugins(args.plugin)
ensure_config_yaml(pm)
ensure_admins(args.admin) ensure_admins(args.admin)
ensure_usergroups() ensure_usergroups()
ensure_user_environment(args.user_requirements_txt_url) ensure_user_environment(args.user_requirements_txt_url)
@@ -416,7 +452,6 @@ def main():
ensure_node() ensure_node()
ensure_jupyterhub_package(HUB_ENV_PREFIX) ensure_jupyterhub_package(HUB_ENV_PREFIX)
ensure_chp_package(HUB_ENV_PREFIX) ensure_chp_package(HUB_ENV_PREFIX)
ensure_config_yaml(pm)
ensure_jupyterlab_extensions() ensure_jupyterlab_extensions()
ensure_jupyterhub_service(HUB_ENV_PREFIX) ensure_jupyterhub_service(HUB_ENV_PREFIX)
ensure_jupyterhub_running() ensure_jupyterhub_running()

View File

@@ -8,7 +8,7 @@ from glob import glob
from systemdspawner import SystemdSpawner from systemdspawner import SystemdSpawner
from tljh import user, configurer 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): class CustomSpawner(SystemdSpawner):
@@ -50,6 +50,6 @@ configurer.apply_config(config_overrides, c)
# Load arbitrary .py config files if they exist. # Load arbitrary .py config files if they exist.
# This is our escape hatch # 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: for ec in extra_configs:
load_subconfig(ec) load_subconfig(ec)