mirror of
https://github.com/jupyterhub/the-littlest-jupyterhub.git
synced 2025-12-18 21:54:05 +08:00
Move conda wrappers to their own module
This commit is contained in:
@@ -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
|
sudo access. Code here can block, since it all runs before JupyterHub
|
||||||
starts.
|
starts.
|
||||||
"""
|
"""
|
||||||
import json
|
from tljh import conda
|
||||||
import subprocess
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
c.JupyterHub.spawner_class = 'systemdspawner.SystemdSpawner'
|
c.JupyterHub.spawner_class = 'systemdspawner.SystemdSpawner'
|
||||||
@@ -22,46 +21,8 @@ here = os.getcwd()
|
|||||||
|
|
||||||
user_environment_prefix = os.path.join(here, 'user-environment')
|
user_environment_prefix = os.path.join(here, 'user-environment')
|
||||||
|
|
||||||
def ensure_conda_env(prefix):
|
conda.ensure_conda_env(user_environment_prefix)
|
||||||
"""
|
conda.ensure_conda_packages(user_environment_prefix, ['notebook', 'jupyterhub'])
|
||||||
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'])
|
|
||||||
|
|
||||||
c.SystemdSpawner.extra_paths = [os.path.join(user_environment_prefix, 'bin')]
|
c.SystemdSpawner.extra_paths = [os.path.join(user_environment_prefix, 'bin')]
|
||||||
c.SystemdSpawner.use_sudo = True
|
c.SystemdSpawner.use_sudo = True
|
||||||
0
tljh/__init__.py
Normal file
0
tljh/__init__.py
Normal file
48
tljh/conda.py
Normal file
48
tljh/conda.py
Normal file
@@ -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
|
||||||
Reference in New Issue
Block a user