From 6dc68210c20dbd3be515e5a4c0c1444496eccd74 Mon Sep 17 00:00:00 2001 From: yuvipanda Date: Tue, 26 Jun 2018 04:14:29 -0700 Subject: [PATCH] Move conda wrappers to their own module --- jupyterhub_config.py | 47 ++++--------------------------------------- tljh/__init__.py | 0 tljh/conda.py | 48 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 43 deletions(-) create mode 100644 tljh/__init__.py create mode 100644 tljh/conda.py diff --git a/jupyterhub_config.py b/jupyterhub_config.py index d1b77a5..7e75a96 100644 --- a/jupyterhub_config.py +++ b/jupyterhub_config.py @@ -11,8 +11,7 @@ This code will run as an unprivileged user, but with unlimited sudo access. Code here can block, since it all runs before JupyterHub starts. """ -import json -import subprocess +from tljh import conda import os c.JupyterHub.spawner_class = 'systemdspawner.SystemdSpawner' @@ -22,46 +21,8 @@ here = os.getcwd() user_environment_prefix = os.path.join(here, 'user-environment') -def ensure_conda_env(prefix): - """ - Ensure a conda environment in the prefix - """ - abspath = os.path.abspath(prefix) - try: - output = json.loads( - subprocess.check_output(['conda', 'create', '--json', '--prefix', abspath]).decode() - ) - except subprocess.CalledProcessError as e: - output = json.loads(e.output.decode()) - if 'error' in output and output['error'] == f'CondaValueError: prefix already exists: {abspath}': - return - raise - if 'success' in output and output['success'] == True: - return - -def ensure_conda_packages(prefix, packages): - """ - Ensure packages are installed in the conda prefix - """ - abspath = os.path.abspath(prefix) - raw_output = subprocess.check_output([ - 'conda', 'install', - '--json', - '--prefix', abspath - ] + packages).decode() - # `conda install` outputs JSON lines for fetch updates, - # and a undelimited output at the end. There is no reasonable way to - # parse this outside of this kludge. - filtered_output = '\n'.join([ - l for l in raw_output.split('\n') - if not l.startswith('{"fetch"') - ]) - output = json.loads(filtered_output) - if 'success' in output and output['success'] == True: - return - -ensure_conda_env(user_environment_prefix) -ensure_conda_packages(user_environment_prefix, ['notebook', 'jupyterhub']) +conda.ensure_conda_env(user_environment_prefix) +conda.ensure_conda_packages(user_environment_prefix, ['notebook', 'jupyterhub']) c.SystemdSpawner.extra_paths = [os.path.join(user_environment_prefix, 'bin')] -c.SystemdSpawner.use_sudo = True \ No newline at end of file +c.SystemdSpawner.use_sudo = True diff --git a/tljh/__init__.py b/tljh/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tljh/conda.py b/tljh/conda.py new file mode 100644 index 0000000..19427a8 --- /dev/null +++ b/tljh/conda.py @@ -0,0 +1,48 @@ +""" +Wrap conda commandline program +""" +import os +import subprocess +import json + + +def ensure_conda_env(prefix): + """ + Ensure a conda environment in the prefix + """ + abspath = os.path.abspath(prefix) + try: + output = json.loads( + subprocess.check_output(['conda', 'create', '--json', '--prefix', abspath]).decode() + ) + except subprocess.CalledProcessError as e: + output = json.loads(e.output.decode()) + if 'error' in output and output['error'] == f'CondaValueError: prefix already exists: {abspath}': + return + raise + if 'success' in output and output['success'] == True: + return + + +def ensure_conda_packages(prefix, packages): + """ + Ensure packages are installed in the conda prefix + """ + abspath = os.path.abspath(prefix) + # Let subprocess errors propagate + # FIXME: raise different exception when using + raw_output = subprocess.check_output([ + 'conda', 'install', + '--json', + '--prefix', abspath + ] + packages).decode() + # `conda install` outputs JSON lines for fetch updates, + # and a undelimited output at the end. There is no reasonable way to + # parse this outside of this kludge. + filtered_output = '\n'.join([ + l for l in raw_output.split('\n') + if not l.startswith('{"fetch"') + ]) + output = json.loads(filtered_output) + if 'success' in output and output['success'] == True: + return