mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-10 11:33:01 +00:00
persist user_options
remember user_options from the previous run this allows user options set via spawn form to be re-used when restarting e.g. a named server via the api
This commit is contained in:
24
jupyterhub/alembic/versions/4dc2d5a8c53c_user_options.py
Normal file
24
jupyterhub/alembic/versions/4dc2d5a8c53c_user_options.py
Normal file
@@ -0,0 +1,24 @@
|
||||
"""persist user_options
|
||||
|
||||
Revision ID: 4dc2d5a8c53c
|
||||
Revises: 896818069c98
|
||||
Create Date: 2019-02-28 14:14:27.423927
|
||||
|
||||
"""
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '4dc2d5a8c53c'
|
||||
down_revision = '896818069c98'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from jupyterhub.orm import JSONDict
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.add_column('spawners', sa.Column('user_options', JSONDict()))
|
||||
|
||||
|
||||
def downgrade():
|
||||
op.drop_column('spawners', sa.Column('user_options'))
|
@@ -216,6 +216,7 @@ class Spawner(Base):
|
||||
|
||||
started = Column(DateTime)
|
||||
last_activity = Column(DateTime, nullable=True)
|
||||
user_options = Column(JSONDict)
|
||||
|
||||
# properties on the spawner wrapper
|
||||
# some APIs get these low-level objects
|
||||
|
@@ -517,6 +517,58 @@ async def test_spawn(app):
|
||||
assert app.users.count_active_users()['pending'] == 0
|
||||
|
||||
|
||||
async def test_user_options(app, username):
|
||||
db = app.db
|
||||
name = username
|
||||
user = add_user(db, app=app, name=name)
|
||||
options = {'s': ['value'], 'i': 5}
|
||||
before_servers = sorted(db.query(orm.Server), key=lambda s: s.url)
|
||||
r = await api_request(
|
||||
app, 'users', name, 'server', method='post', data=json.dumps(options)
|
||||
)
|
||||
assert r.status_code == 201
|
||||
assert 'pid' in user.orm_spawners[''].state
|
||||
app_user = app.users[name]
|
||||
assert app_user.spawner is not None
|
||||
spawner = app_user.spawner
|
||||
assert spawner.user_options == options
|
||||
assert spawner.orm_spawner.user_options == options
|
||||
|
||||
# stop the server
|
||||
r = await api_request(app, 'users', name, 'server', method='delete')
|
||||
|
||||
# orm_spawner still exists and has a reference to the user_options
|
||||
assert spawner.orm_spawner.user_options == options
|
||||
|
||||
# spawn again, no options specified
|
||||
# should re-use options from last spawn
|
||||
r = await api_request(app, 'users', name, 'server', method='post')
|
||||
assert r.status_code == 201
|
||||
assert 'pid' in user.orm_spawners[''].state
|
||||
app_user = app.users[name]
|
||||
assert app_user.spawner is not None
|
||||
spawner = app_user.spawner
|
||||
assert spawner.user_options == options
|
||||
|
||||
# stop the server
|
||||
r = await api_request(app, 'users', name, 'server', method='delete')
|
||||
|
||||
# spawn again, new options specified
|
||||
# should override options from last spawn
|
||||
new_options = {'key': 'value'}
|
||||
r = await api_request(
|
||||
app, 'users', name, 'server', method='post', data=json.dumps(new_options)
|
||||
)
|
||||
assert r.status_code == 201
|
||||
assert 'pid' in user.orm_spawners[''].state
|
||||
app_user = app.users[name]
|
||||
assert app_user.spawner is not None
|
||||
spawner = app_user.spawner
|
||||
assert spawner.user_options == new_options
|
||||
# saved in db
|
||||
assert spawner.orm_spawner.user_options == new_options
|
||||
|
||||
|
||||
async def test_spawn_handler(app):
|
||||
"""Test that the requesting Handler is passed to Spawner.handler"""
|
||||
db = app.db
|
||||
|
@@ -479,8 +479,17 @@ class User:
|
||||
# pass requesting handler to the spawner
|
||||
# e.g. for processing GET params
|
||||
spawner.handler = handler
|
||||
|
||||
# Passing user_options to the spawner
|
||||
spawner.user_options = options or {}
|
||||
if options is None:
|
||||
# options unspecified, load from db which should have the previous value
|
||||
options = spawner.orm_spawner.user_options or {}
|
||||
else:
|
||||
# options specified, save for use as future defaults
|
||||
spawner.orm_spawner.user_options = options
|
||||
db.commit()
|
||||
|
||||
spawner.user_options = options
|
||||
# we are starting a new server, make sure it doesn't restore state
|
||||
spawner.clear_state()
|
||||
|
||||
|
Reference in New Issue
Block a user