mirror of
https://github.com/jupyterhub/the-littlest-jupyterhub.git
synced 2025-12-18 21:54:05 +08:00
Separate jupyterhub & chp services
Allows restarting hub for config changes without disrupting user service!
This commit is contained in:
@@ -3,6 +3,7 @@ import os
|
|||||||
import tljh.systemd as systemd
|
import tljh.systemd as systemd
|
||||||
import tljh.conda as conda
|
import tljh.conda as conda
|
||||||
from tljh import user
|
from tljh import user
|
||||||
|
import secrets
|
||||||
|
|
||||||
INSTALL_PREFIX = os.environ.get('TLJH_INSTALL_PREFIX', '/opt/tljh')
|
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')
|
||||||
@@ -12,15 +13,27 @@ HERE = os.path.abspath(os.path.dirname(__file__))
|
|||||||
|
|
||||||
|
|
||||||
def ensure_jupyterhub_service(prefix):
|
def ensure_jupyterhub_service(prefix):
|
||||||
|
"""
|
||||||
|
Ensure JupyterHub & CHP Services are set up properly
|
||||||
|
"""
|
||||||
with open(os.path.join(HERE, 'systemd-units', 'jupyterhub.service')) as f:
|
with open(os.path.join(HERE, 'systemd-units', 'jupyterhub.service')) as f:
|
||||||
unit_template = f.read()
|
hub_unit_template = f.read()
|
||||||
|
|
||||||
unit = unit_template.format(
|
with open(os.path.join(HERE, 'systemd-units', 'configurable-http-proxy.service')) as f:
|
||||||
|
proxy_unit_template = f.read()
|
||||||
|
|
||||||
|
unit_params = dict(
|
||||||
python_interpreter_path=sys.executable,
|
python_interpreter_path=sys.executable,
|
||||||
jupyterhub_config_path=os.path.join(HERE, 'jupyterhub_config.py'),
|
jupyterhub_config_path=os.path.join(HERE, 'jupyterhub_config.py'),
|
||||||
install_prefix=INSTALL_PREFIX
|
install_prefix=INSTALL_PREFIX
|
||||||
)
|
)
|
||||||
systemd.install_unit('jupyterhub.service', unit)
|
systemd.install_unit('configurable-http-proxy.service', proxy_unit_template.format(**unit_params))
|
||||||
|
systemd.install_unit('jupyterhub.service', hub_unit_template.format(**unit_params))
|
||||||
|
|
||||||
|
# Set up proxy / hub secret oken if it is not already setup
|
||||||
|
if not os.path.exists('/etc/jupyterhub/configurable-http-proxy.secret'):
|
||||||
|
with open('/etc/jupyterhub/configurable-http-proxy.secret', 'w') as f:
|
||||||
|
f.write('CONFIGPROXY_AUTH_TOKEN=' + secrets.token_hex(32))
|
||||||
|
|
||||||
|
|
||||||
def ensure_jupyterhub_package(prefix):
|
def ensure_jupyterhub_package(prefix):
|
||||||
@@ -53,4 +66,5 @@ conda.ensure_conda_packages(USER_ENV_PREFIX, [
|
|||||||
'notebook==5.5.0'
|
'notebook==5.5.0'
|
||||||
])
|
])
|
||||||
systemd.reload_daemon()
|
systemd.reload_daemon()
|
||||||
|
systemd.start_service('configurable-http-proxy')
|
||||||
systemd.start_service('jupyterhub')
|
systemd.start_service('jupyterhub')
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ class CustomSpawner(SystemdSpawner):
|
|||||||
|
|
||||||
c.JupyterHub.spawner_class = CustomSpawner
|
c.JupyterHub.spawner_class = CustomSpawner
|
||||||
|
|
||||||
|
c.ConfigurableHTTPProxy.should_start = False
|
||||||
|
|
||||||
c.SystemdSpawner.extra_paths = [os.path.join(USER_ENV_PREFIX, 'bin')]
|
c.SystemdSpawner.extra_paths = [os.path.join(USER_ENV_PREFIX, 'bin')]
|
||||||
c.SystemdSpawner.use_sudo = True
|
c.SystemdSpawner.use_sudo = True
|
||||||
|
|
||||||
|
|||||||
22
tljh/systemd-units/configurable-http-proxy.service
Normal file
22
tljh/systemd-units/configurable-http-proxy.service
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Template file for Configurable HTTP Proxy systemd service
|
||||||
|
# Uses simple string.format() for 'templating'
|
||||||
|
[Unit]
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=root
|
||||||
|
Restart=always
|
||||||
|
# chp process should have no write access anywhere on disk
|
||||||
|
ProtectHome=tmpfs
|
||||||
|
ProtectSystem=strict
|
||||||
|
PrivateTmp=yes
|
||||||
|
PrivateDevices=yes
|
||||||
|
ProtectKernelTunables=yes
|
||||||
|
ProtectKernelModules=yes
|
||||||
|
EnvironmentFile=/etc/jupyterhub/configurable-http-proxy.secret
|
||||||
|
ExecStart={install_prefix}/hub/bin/configurable-http-proxy \
|
||||||
|
--ip 0.0.0.0 \
|
||||||
|
--port 80 \
|
||||||
|
--api-ip 127.0.0.1 \
|
||||||
|
--api-port 8001 \
|
||||||
|
--error-target http://127.0.0.1:8081/hub/error
|
||||||
@@ -1,13 +1,22 @@
|
|||||||
# Template file for JupyterHub systemd service
|
# Template file for JupyterHub systemd service
|
||||||
# Runs both JupyterHub and ConfigurableHTTPProxy
|
|
||||||
# Uses simple string.format() for 'templating'
|
# Uses simple string.format() for 'templating'
|
||||||
[Unit]
|
[Unit]
|
||||||
Wants=network-online.target
|
Wants=configurable-http-proxy.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
User=root
|
User=root
|
||||||
Restart=always
|
Restart=always
|
||||||
Environment=TLJH_INSTALL_PREFIX={install_prefix}
|
# jupyterhub process should have no access to home directories
|
||||||
|
ProtectHome=tmpfs
|
||||||
|
# Use a persistent, permissioned state directory for db + cookie secrets
|
||||||
StateDirectory=jupyterhub
|
StateDirectory=jupyterhub
|
||||||
WorkingDirectory=/var/lib/jupyterhub
|
WorkingDirectory=/var/lib/jupyterhub
|
||||||
|
# Protect bits that are normally shared across the system
|
||||||
|
PrivateTmp=yes
|
||||||
|
PrivateDevices=yes
|
||||||
|
ProtectKernelTunables=yes
|
||||||
|
ProtectKernelModules=yes
|
||||||
|
# Source CONFIGPROXY_AUTH_TOKEN from here!
|
||||||
|
EnvironmentFile=/etc/jupyterhub/configurable-http-proxy.secret
|
||||||
|
Environment=TLJH_INSTALL_PREFIX={install_prefix}
|
||||||
ExecStart={python_interpreter_path} -m jupyterhub.app -f {jupyterhub_config_path}
|
ExecStart={python_interpreter_path} -m jupyterhub.app -f {jupyterhub_config_path}
|
||||||
|
|||||||
Reference in New Issue
Block a user