relies on CHP's host-based routing (a feature I didn't add!)
requires wildcard DNS and wildcard SSL for a proper setup
still lots to workout and cleanup in terms of cookies and where to use host, domain, path, but it works locally.
in check_routes, it has been reported that users without a running server are attempted to be added.
So something is wrong, either in sqlalchemy or my understanding of what it does (likely the latter),
because a filter for users with a non-None server is returning at least one result whose server is None.
This is to resolve the 'Network is Unreachable' error experienced by a few when JupyterHUB is connecting to localhost.
On most recent linux OS versions like CentOS 6, 7, Red Hat 6, 7, Oracle Linux 6, 7, etc, the hosts file (/etc/hosts) usually has a line to make the server IPv6-ready:
::1 localhost
even if the given server actually has no IPv6 permissioned. In such case the Python socket library when connecting to 'localhost' will try to connect via the IPv6 protocol - which will fail with the 'Network is Unreachable' error.
To solve this we capture this error and try to reconnect on 127.0.0.1 instead of localhost, alias forcing the user of the IPv4 protocol.
allows setup/cleanup to be performed by the authenticator
use this to open PAM sessions at spawn
and close them at stop,
rather than open at login and never close.
Server started, but never became accessible:
> Failed to reach your server.
> Please try again later.
> Contact admin if the issue persists.
Server failed to start (errors in Spawner):
> Failed to start your server.
> Please contact admin.
e.g. docker, which can take a long time to stop,
especially if several docker actions are already queued.
Use status `202: Accepted` for API replies sent with spawn/stop still pending
such as VMs, batch and cloud services, etc. which can take minutes to start.
- Spawner.start_timeout sets a limit for true failure,
at which point spawner should be considered dead.
- Handler.spawn_single_user only waits up to 10 seconds
before returning. It can now return with a spawner still pending.
- Record User.spawn_pending state, and render 'pending' page
while server is starting but not started.
use single cookie_id, since cookies themselves are already unique via `set_secure_cookie`
resetting cookie_id effectively logs out all browser sessions for a given user
we can store hash+salt ourselves.
Since we need to implement prefix filtering, etc. ourselves,
there is little benefit to adding a large dependency just for implicit hashing.
- use PasswordType
- store first 4 bytes for filtering by prefix
since we can't filter by equality on the hashed value.
- user.new_foo_token() returns token string, not ORM object
- call start/stop_polling outside Spawner
(avoids need for custom spawners to reimplement)
- don't clear state when stopping Spawner
(should enable spawners to resume)