mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-15 22:13:00 +00:00
add —cull-users to cull_idle_servers
allows deleting idle users in addition to servers for temp-user cases such as binder/tmpnb
This commit is contained in:
@@ -40,8 +40,11 @@ from tornado.options import define, options, parse_command_line
|
|||||||
|
|
||||||
|
|
||||||
@coroutine
|
@coroutine
|
||||||
def cull_idle(url, api_token, timeout):
|
def cull_idle(url, api_token, timeout, cull_users=False):
|
||||||
"""cull idle single-user servers"""
|
"""Shutdown idle single-user servers
|
||||||
|
|
||||||
|
If cull_users, inactive *users* will be deleted as well.
|
||||||
|
"""
|
||||||
auth_header = {
|
auth_header = {
|
||||||
'Authorization': 'token %s' % api_token
|
'Authorization': 'token %s' % api_token
|
||||||
}
|
}
|
||||||
@@ -54,26 +57,50 @@ def cull_idle(url, api_token, timeout):
|
|||||||
resp = yield client.fetch(req)
|
resp = yield client.fetch(req)
|
||||||
users = json.loads(resp.body.decode('utf8', 'replace'))
|
users = json.loads(resp.body.decode('utf8', 'replace'))
|
||||||
futures = []
|
futures = []
|
||||||
for user in users:
|
|
||||||
last_activity = parse_date(user['last_activity'])
|
@coroutine
|
||||||
if user['server'] and last_activity < cull_limit:
|
def cull_one(user, last_activity):
|
||||||
app_log.info("Culling %s (inactive since %s)", user['name'], last_activity)
|
"""cull one user"""
|
||||||
|
|
||||||
|
# shutdown server first. Hub doesn't allow deleting users with running servers.
|
||||||
|
if user['server']:
|
||||||
|
app_log.info("Culling server for %s (inactive since %s)", user['name'], last_activity)
|
||||||
req = HTTPRequest(url=url + '/users/%s/server' % user['name'],
|
req = HTTPRequest(url=url + '/users/%s/server' % user['name'],
|
||||||
method='DELETE',
|
method='DELETE',
|
||||||
headers=auth_header,
|
headers=auth_header,
|
||||||
)
|
)
|
||||||
futures.append((user['name'], client.fetch(req)))
|
yield client.fetch(req)
|
||||||
elif user['server'] and last_activity > cull_limit:
|
if cull_users:
|
||||||
|
app_log.info("Culling user %s (inactive since %s)", user['name'], last_activity)
|
||||||
|
req = HTTPRequest(url=url + '/users/%s' % user['name'],
|
||||||
|
method='DELETE',
|
||||||
|
headers=auth_header,
|
||||||
|
)
|
||||||
|
yield client.fetch(req)
|
||||||
|
|
||||||
|
for user in users:
|
||||||
|
if not user['server'] and not cull_users:
|
||||||
|
# server not running and not culling users, nothing to do
|
||||||
|
continue
|
||||||
|
last_activity = parse_date(user['last_activity'])
|
||||||
|
if last_activity < cull_limit:
|
||||||
|
futures.append((user['name'], cull_one(user, last_activity)))
|
||||||
|
else:
|
||||||
app_log.debug("Not culling %s (active since %s)", user['name'], last_activity)
|
app_log.debug("Not culling %s (active since %s)", user['name'], last_activity)
|
||||||
|
|
||||||
for (name, f) in futures:
|
for (name, f) in futures:
|
||||||
yield f
|
yield f
|
||||||
app_log.debug("Finished culling %s", name)
|
app_log.debug("Finished culling %s", name)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
define('url', default=os.environ.get('JUPYTERHUB_API_URL'), help="The JupyterHub API URL")
|
define('url', default=os.environ.get('JUPYTERHUB_API_URL'), help="The JupyterHub API URL")
|
||||||
define('timeout', default=600, help="The idle timeout (in seconds)")
|
define('timeout', default=600, help="The idle timeout (in seconds)")
|
||||||
define('cull_every', default=0, help="The interval (in seconds) for checking for idle servers to cull")
|
define('cull_every', default=0, help="The interval (in seconds) for checking for idle servers to cull")
|
||||||
|
define('cull_users', default=False,
|
||||||
|
help="""Cull users in addition to servers.
|
||||||
|
This is for use in temporary-user cases such as tmpnb.""",
|
||||||
|
)
|
||||||
|
|
||||||
parse_command_line()
|
parse_command_line()
|
||||||
if not options.cull_every:
|
if not options.cull_every:
|
||||||
@@ -82,7 +109,7 @@ if __name__ == '__main__':
|
|||||||
api_token = os.environ['JUPYTERHUB_API_TOKEN']
|
api_token = os.environ['JUPYTERHUB_API_TOKEN']
|
||||||
|
|
||||||
loop = IOLoop.current()
|
loop = IOLoop.current()
|
||||||
cull = lambda : cull_idle(options.url, api_token, options.timeout)
|
cull = lambda : cull_idle(options.url, api_token, options.timeout, options.cull_users)
|
||||||
# run once before scheduling periodic call
|
# run once before scheduling periodic call
|
||||||
loop.run_sync(cull)
|
loop.run_sync(cull)
|
||||||
# schedule periodic cull
|
# schedule periodic cull
|
||||||
|
Reference in New Issue
Block a user