move config migration to its own file

This commit is contained in:
Min RK
2018-08-31 12:17:16 +02:00
parent 37ad207be9
commit 5df106fa82
5 changed files with 139 additions and 63 deletions

View File

@@ -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'))

57
tests/test_migrator.py Normal file
View File

@@ -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

View File

@@ -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):
"""

View File

@@ -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:

69
tljh/migrator.py Normal file
View File

@@ -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"),
)