mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-09 19:13:03 +00:00
support removing named servers
This commit is contained in:
@@ -217,6 +217,13 @@ paths:
|
||||
in: path
|
||||
required: true
|
||||
type: string
|
||||
- name: remove
|
||||
description: |
|
||||
Whether to fully remove the server, rather than just stop it.
|
||||
Removing a server deletes things like the state of the stopped server.
|
||||
in: body
|
||||
required: false
|
||||
type: boolean
|
||||
responses:
|
||||
'201':
|
||||
description: The user's notebook named-server has started
|
||||
|
@@ -378,29 +378,52 @@ class UserServerAPIHandler(APIHandler):
|
||||
@admin_or_self
|
||||
async def delete(self, name, server_name=''):
|
||||
user = self.find_user(name)
|
||||
options = self.get_json_body()
|
||||
remove = (options or {}).get('remove', False)
|
||||
|
||||
|
||||
def _remove_spawner(f=None):
|
||||
if f and f.exception():
|
||||
return
|
||||
self.log.info("Deleting spawner %s", spawner._log_name)
|
||||
self.db.delete(spawner.orm_spawner)
|
||||
self.db.commit()
|
||||
|
||||
if server_name:
|
||||
if not self.allow_named_servers:
|
||||
raise web.HTTPError(400, "Named servers are not enabled.")
|
||||
if server_name not in user.spawners:
|
||||
if server_name not in user.orm_spawners:
|
||||
raise web.HTTPError(404, "%s has no server named '%s'" % (name, server_name))
|
||||
elif remove:
|
||||
raise web.HTTPError(400, "Cannot delete the default server")
|
||||
|
||||
spawner = user.spawners[server_name]
|
||||
if spawner.pending == 'stop':
|
||||
self.log.debug("%s already stopping", spawner._log_name)
|
||||
self.set_header('Content-Type', 'text/plain')
|
||||
self.set_status(202)
|
||||
if remove:
|
||||
spawner._stop_future.add_done_callback(_remove_spawner)
|
||||
return
|
||||
|
||||
if not spawner.ready:
|
||||
if spawner.pending:
|
||||
raise web.HTTPError(
|
||||
400, "%s is not running %s" %
|
||||
(spawner._log_name, '(pending: %s)' % spawner.pending if spawner.pending else '')
|
||||
400, "%s is pending %s, please wait" % (spawner._log_name, spawner.pending)
|
||||
)
|
||||
|
||||
stop_future = None
|
||||
if spawner.ready:
|
||||
# include notify, so that a server that died is noticed immediately
|
||||
status = await spawner.poll_and_notify()
|
||||
if status is not None:
|
||||
raise web.HTTPError(400, "%s is not running" % spawner._log_name)
|
||||
await self.stop_single_user(user, server_name)
|
||||
if status is None:
|
||||
stop_future = await self.stop_single_user(user, server_name)
|
||||
|
||||
if remove:
|
||||
if stop_future:
|
||||
stop_future.add_done_callback(_remove_spawner)
|
||||
else:
|
||||
_remove_spawner()
|
||||
|
||||
status = 202 if spawner._stop_pending else 204
|
||||
self.set_header('Content-Type', 'text/plain')
|
||||
self.set_status(status)
|
||||
|
@@ -677,7 +677,8 @@ def test_slow_spawn(app, no_patience, slow_spawn):
|
||||
assert not app_user.spawner._stop_pending
|
||||
assert app_user.spawner is not None
|
||||
r = yield api_request(app, 'users', name, 'server', method='delete')
|
||||
assert r.status_code == 400
|
||||
# 204 deleted if there's no such server
|
||||
assert r.status_code == 204
|
||||
assert app.users.count_active_users()['pending'] == 0
|
||||
assert app.users.count_active_users()['active'] == 0
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
"""Tests for named servers"""
|
||||
import json
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
@@ -134,6 +135,21 @@ def test_delete_named_server(app, named_servers):
|
||||
'auth_state': None,
|
||||
'servers': {},
|
||||
})
|
||||
# wrapper Spawner is gone
|
||||
assert servername not in user.spawners
|
||||
# low-level record still exists
|
||||
assert servername in user.orm_spawners
|
||||
|
||||
r = yield api_request(
|
||||
app, 'users', username, 'servers', servername,
|
||||
method='delete',
|
||||
data=json.dumps({'remove': True}),
|
||||
)
|
||||
r.raise_for_status()
|
||||
assert r.status_code == 204
|
||||
# low-level record is now removes
|
||||
assert servername not in user.orm_spawners
|
||||
|
||||
|
||||
@pytest.mark.gen_test
|
||||
def test_named_server_disabled(app):
|
||||
|
Reference in New Issue
Block a user