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,6 +25,9 @@ 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.
|
||||
The Spawner itself is passed as parameter to your hook and you can easily get the contextual information out of the spawning process.
|
||||
|
||||
Similarly, there may be cases where you would like to clean up after a spawner stops.
|
||||
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.
|
||||
|
@@ -2,6 +2,7 @@
|
||||
# create a directory for the user before the spawner starts
|
||||
|
||||
import os
|
||||
import shutil
|
||||
def create_dir_hook(spawner):
|
||||
username = spawner.user.name # get the 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
|
||||
# ...
|
||||
|
||||
# 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.post_spawn_hook = clean_dir_hook
|
||||
|
||||
# Use the DockerSpawner to serve your users' notebooks
|
||||
c.JupyterHub.spawner_class = 'dockerspawner.DockerSpawner'
|
||||
|
@@ -515,6 +515,15 @@ class Spawner(LoggingConfigurable):
|
||||
"""
|
||||
).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):
|
||||
"""Restore state of spawner from database.
|
||||
|
||||
@@ -692,6 +701,13 @@ class Spawner(LoggingConfigurable):
|
||||
if self.pre_spawn_hook:
|
||||
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
|
||||
def _progress_url(self):
|
||||
return self.user.progress_url(self.name)
|
||||
|
@@ -559,6 +559,8 @@ class User:
|
||||
finally:
|
||||
spawner.orm_spawner.started = None
|
||||
self.db.commit()
|
||||
# trigger post-spawner hook
|
||||
await maybe_future(spawner.run_post_spawn_hook())
|
||||
# trigger post-spawner hook on authenticator
|
||||
auth = spawner.authenticator
|
||||
try:
|
||||
|
Reference in New Issue
Block a user