mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-07 18:14:10 +00:00
Add post-spawn hook
This commit is contained in:
@@ -25,8 +25,11 @@ Another use would be to copy initial content, such as tutorial files or referenc
|
|||||||
You can define your own bootstrap process by implementing a `pre_spawn_hook` on any spawner.
|
You can define your own bootstrap process by implementing a `pre_spawn_hook` on any spawner.
|
||||||
The Spawner itself is passed as parameter to your hook and you can easily get the contextual information out of the spawning process.
|
The Spawner itself is passed as parameter to your hook and you can easily get the contextual information out of the spawning process.
|
||||||
|
|
||||||
If you implement a hook, make sure that it is *idempotent*. It will be executed every time
|
Similarly, there may be cases where you would like to clean up after a spawner stops.
|
||||||
a notebook server is spawned to the user. That means you should somehow
|
You may implement a `post_spawn_hook` that is always executed after the spawner stops.
|
||||||
|
|
||||||
|
If you implement a hook, make sure that it is *idempotent*. It will be executed every time
|
||||||
|
a notebook server is spawned to the user. That means you should somehow
|
||||||
ensure that things which should run only once are not running again and again.
|
ensure that things which should run only once are not running again and again.
|
||||||
For example, before you create a directory, check if it exists.
|
For example, before you create a directory, check if it exists.
|
||||||
|
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
# create a directory for the user before the spawner starts
|
# create a directory for the user before the spawner starts
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
def create_dir_hook(spawner):
|
def create_dir_hook(spawner):
|
||||||
username = spawner.user.name # get the username
|
username = spawner.user.name # get the username
|
||||||
volume_path = os.path.join('/volumes/jupyterhub', username)
|
volume_path = os.path.join('/volumes/jupyterhub', username)
|
||||||
@@ -10,8 +11,15 @@ def create_dir_hook(spawner):
|
|||||||
# now do whatever you think your user needs
|
# now do whatever you think your user needs
|
||||||
# ...
|
# ...
|
||||||
|
|
||||||
# attach the hook function to the spawner
|
def clean_dir_hook(spawner):
|
||||||
|
username = spawner.user.name # get the username
|
||||||
|
temp_path = os.path.join('/volumes/jupyterhub', username, 'temp')
|
||||||
|
if os.path.exists(temp_path) and os.path.isdir(temp_path):
|
||||||
|
shutil.rmtree(temp_path)
|
||||||
|
|
||||||
|
# attach the hook functions to the spawner
|
||||||
c.Spawner.pre_spawn_hook = create_dir_hook
|
c.Spawner.pre_spawn_hook = create_dir_hook
|
||||||
|
c.Spawner.post_spawn_hook = clean_dir_hook
|
||||||
|
|
||||||
# Use the DockerSpawner to serve your users' notebooks
|
# Use the DockerSpawner to serve your users' notebooks
|
||||||
c.JupyterHub.spawner_class = 'dockerspawner.DockerSpawner'
|
c.JupyterHub.spawner_class = 'dockerspawner.DockerSpawner'
|
||||||
|
@@ -515,6 +515,15 @@ class Spawner(LoggingConfigurable):
|
|||||||
"""
|
"""
|
||||||
).tag(config=True)
|
).tag(config=True)
|
||||||
|
|
||||||
|
post_spawn_hook = Any(
|
||||||
|
help="""
|
||||||
|
An optional hook function that you can implement to do work after
|
||||||
|
the spawner stops.
|
||||||
|
|
||||||
|
This can be set independent of any concrete spawner implementation.
|
||||||
|
"""
|
||||||
|
).tag(config=True)
|
||||||
|
|
||||||
def load_state(self, state):
|
def load_state(self, state):
|
||||||
"""Restore state of spawner from database.
|
"""Restore state of spawner from database.
|
||||||
|
|
||||||
@@ -692,6 +701,13 @@ class Spawner(LoggingConfigurable):
|
|||||||
if self.pre_spawn_hook:
|
if self.pre_spawn_hook:
|
||||||
return self.pre_spawn_hook(self)
|
return self.pre_spawn_hook(self)
|
||||||
|
|
||||||
|
def run_post_spawn_hook(self):
|
||||||
|
"""Run the post_spawn_hook if defined"""
|
||||||
|
try:
|
||||||
|
return self.post_spawn_hook(self)
|
||||||
|
except Exception:
|
||||||
|
self.log.exception("post_spawn_hook failed with exception: %s", self)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _progress_url(self):
|
def _progress_url(self):
|
||||||
return self.user.progress_url(self.name)
|
return self.user.progress_url(self.name)
|
||||||
|
@@ -559,6 +559,8 @@ class User:
|
|||||||
finally:
|
finally:
|
||||||
spawner.orm_spawner.started = None
|
spawner.orm_spawner.started = None
|
||||||
self.db.commit()
|
self.db.commit()
|
||||||
|
# trigger post-spawner hook
|
||||||
|
await maybe_future(spawner.run_post_spawn_hook())
|
||||||
# trigger post-spawner hook on authenticator
|
# trigger post-spawner hook on authenticator
|
||||||
auth = spawner.authenticator
|
auth = spawner.authenticator
|
||||||
try:
|
try:
|
||||||
|
Reference in New Issue
Block a user