mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-13 21:13:01 +00:00
compare hub and single-user server versions
in both directions - Hub checks singleuser server on spawn and singleuser server checks Hub on startup if minor versions mismatch, log at warning level, otherwise debug
This commit is contained in:
@@ -1 +1 @@
|
||||
from .version import version_info, __version__
|
||||
from ._version import version_info, __version__
|
||||
|
40
jupyterhub/_version.py
Normal file
40
jupyterhub/_version.py
Normal file
@@ -0,0 +1,40 @@
|
||||
"""JupyterHub version info"""
|
||||
|
||||
# Copyright (c) Jupyter Development Team.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
version_info = (
|
||||
0,
|
||||
8,
|
||||
0,
|
||||
'dev',
|
||||
)
|
||||
|
||||
__version__ = '.'.join(map(str, version_info))
|
||||
|
||||
|
||||
def _check_version(hub_version, singleuser_version, log):
|
||||
"""Compare Hub and single-user server versions"""
|
||||
if not hub_version:
|
||||
log.warning("Hub has no version header, which means it is likely < 0.8. Expected %s", __version__)
|
||||
return
|
||||
|
||||
if not singleuser_version:
|
||||
log.warning("Single-user server has no version header, which means it is likely < 0.8. Expected %s", __version__)
|
||||
return
|
||||
|
||||
# compare minor X.Y versions
|
||||
if hub_version != singleuser_version:
|
||||
from distutils.version import LooseVersion as V
|
||||
hub_major_minor = V(hub_version).version[:2]
|
||||
singleuser_major_minor = V(__version__).version[:2]
|
||||
if singleuser_major_minor == hub_major_minor:
|
||||
# patch-level mismatch or lower, log difference at debug-level
|
||||
# because this should be fine
|
||||
log_method = log.debug
|
||||
else:
|
||||
# log warning-level for more significant mismatch, such as 0.8 vs 0.9, etc.
|
||||
log_method = log.warning
|
||||
log_method("jupyterhub version %s != jupyterhub-singleuser version %s",
|
||||
hub_version, __version__,
|
||||
)
|
@@ -11,7 +11,7 @@ from tornado.ioloop import IOLoop
|
||||
|
||||
from ..utils import admin_only
|
||||
from .base import APIHandler
|
||||
from ..version import __version__
|
||||
from .._version import __version__
|
||||
|
||||
|
||||
class ShutdownAPIHandler(APIHandler):
|
||||
|
@@ -4,12 +4,16 @@
|
||||
# Copyright (c) Jupyter Development Team.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
from distutils.version import LooseVersion as V
|
||||
import os
|
||||
import re
|
||||
from textwrap import dedent
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from jinja2 import ChoiceLoader, FunctionLoader
|
||||
|
||||
from tornado.httpclient import AsyncHTTPClient
|
||||
from tornado import gen
|
||||
from tornado import ioloop
|
||||
from tornado.web import HTTPError
|
||||
|
||||
@@ -37,7 +41,7 @@ from notebook.auth.login import LoginHandler
|
||||
from notebook.auth.logout import LogoutHandler
|
||||
from notebook.base.handlers import IPythonHandler
|
||||
|
||||
from jupyterhub import __version__
|
||||
from ._version import __version__, _check_version
|
||||
from .log import log_request
|
||||
from .services.auth import HubOAuth, HubOAuthenticated, HubOAuthCallbackHandler
|
||||
from .utils import url_path_join
|
||||
@@ -337,7 +341,27 @@ class SingleUserNotebookApp(NotebookApp):
|
||||
path = list(_exclude_home(path))
|
||||
return path
|
||||
|
||||
@gen.coroutine
|
||||
def check_hub_version(self):
|
||||
"""Test a connection to my Hub
|
||||
|
||||
- exit if I can't connect at all
|
||||
- check version and warn on sufficient mismatch
|
||||
"""
|
||||
client = AsyncHTTPClient()
|
||||
try:
|
||||
resp = yield client.fetch(self.hub_api_url)
|
||||
except Exception:
|
||||
self.log.exception("Failed to connect to my Hub at %s. Is it running?", self.hub_api_url)
|
||||
self.exit(1)
|
||||
|
||||
hub_version = resp.headers.get('X-JupyterHub-Version')
|
||||
_check_version(hub_version, __version__, self.log)
|
||||
|
||||
def start(self):
|
||||
self.log.info("Starting jupyterhub-singleuser server version %s", __version__)
|
||||
# start by hitting Hub to check version
|
||||
ioloop.IOLoop.current().run_sync(self.check_hub_version)
|
||||
super(SingleUserNotebookApp, self).start()
|
||||
|
||||
def init_hub_auth(self):
|
||||
|
@@ -12,6 +12,7 @@ from tornado.log import app_log
|
||||
from .utils import url_path_join, default_server_name
|
||||
|
||||
from . import orm
|
||||
from ._version import _check_version, __version__
|
||||
from .objects import Server
|
||||
from traitlets import HasTraits, Any, Dict, observe, default
|
||||
from .spawner import LocalProcessSpawner
|
||||
@@ -328,7 +329,7 @@ class User(HasTraits):
|
||||
db.commit()
|
||||
self.waiting_for_response = True
|
||||
try:
|
||||
yield server.wait_up(http=True, timeout=spawner.http_timeout)
|
||||
resp = yield server.wait_up(http=True, timeout=spawner.http_timeout)
|
||||
except Exception as e:
|
||||
if isinstance(e, TimeoutError):
|
||||
self.log.warning(
|
||||
@@ -353,6 +354,9 @@ class User(HasTraits):
|
||||
), exc_info=True)
|
||||
# raise original TimeoutError
|
||||
raise e
|
||||
else:
|
||||
server_version = resp.headers.get('X-JupyterHub-Version')
|
||||
_check_version(__version__, server_version, self.log)
|
||||
finally:
|
||||
self.waiting_for_response = False
|
||||
self.spawn_pending = False
|
||||
|
@@ -1,13 +0,0 @@
|
||||
"""JupyterHub version info"""
|
||||
|
||||
# Copyright (c) Jupyter Development Team.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
version_info = (
|
||||
0,
|
||||
8,
|
||||
0,
|
||||
'dev',
|
||||
)
|
||||
|
||||
__version__ = '.'.join(map(str, version_info))
|
Reference in New Issue
Block a user