Skip to content

Commit

Permalink
release 0.4.0
Browse files Browse the repository at this point in the history
port marathonspawner for 0.8.0 jupyterhub
  • Loading branch information
vigsterkr committed Oct 8, 2017
1 parent 1b9cf16 commit 79539ff
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 29 deletions.
10 changes: 4 additions & 6 deletions jupyterhub_config.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
import os

c = get_config()

c.JupyterHub.spawner_class = 'marathonspawner.MarathonSpawner'

c.JupyterHub.ip = '0.0.0.0'
c.JupyterHub.hub_ip = '0.0.0.0'

# Don't try to cleanup servers on exit - since in general for k8s, we want
# the hub to be able to restart without losing user containers
c.JupyterHub.cmd = 'start-singleuser.sh'
c.JupyterHub.cleanup_servers = False

c.MarathonSpawner.app_prefix = 'jupyter'
c.MarathonSpawner.app_image = 'jupyterhub/singleuser'
c.MarathonSpawner.app_prefix = 'jupyter'
c.MarathonSpawner.marathon_host = 'http://leader.mesos:8080'
c.MarathonSpawner.ports = [8000]
c.MarathonSpawner.mem_limit = '2G'
c.MarathonSpawner.cpu_limit = 1
c.MarathonSpawner.hub_ip_connect = os.environ['HUB_IP_CONNECT']
c.MarathonSpawner.hub_port_connect = os.environ['HUB_PORT_CONNECT']


c.JupyterHub.authenticator_class = 'dummyauthenticator.DummyAuthenticator'
2 changes: 1 addition & 1 deletion marathonspawner/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '0.3.1'
__version__ = '0.4.0'
69 changes: 47 additions & 22 deletions marathonspawner/marathonspawner.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
import socket
from concurrent.futures import ThreadPoolExecutor
from urllib.parse import urlparse, urlunparse
import warnings

from textwrap import dedent
from tornado import gen
from tornado.concurrent import run_on_executor
from traitlets import Any, Integer, List, Unicode, default
from traitlets import Any, Integer, List, Unicode, default, observe

from marathon import MarathonClient
from marathon.models.app import MarathonApp, MarathonHealthCheck
Expand All @@ -18,10 +19,12 @@

from .volumenaming import default_format_volume_name

import jupyterhub
_jupyterhub_xy = '%i.%i' % (jupyterhub.version_info[:2])

class MarathonSpawner(Spawner):

app_image = Unicode("jupyterhub/singleuser", config=True)
app_image = Unicode("jupyterhub/singleuser:%s" % _jupyterhub_xy, config=True)

app_prefix = Unicode(
"jupyter",
Expand Down Expand Up @@ -76,11 +79,29 @@ class MarathonSpawner(Spawner):
help="Public IP address of the hub"
).tag(config=True)

@observe('hub_ip_connect')
def _ip_connect_changed(self, change):
if jupyterhub.version_info >= (0, 8):
warnings.warn(
"MarathonSpawner.hub_ip_connect is no longer needed with JupyterHub 0.8."
" Use JupyterHub.hub_connect_ip instead.",
DeprecationWarning,
)

hub_port_connect = Integer(
-1,
help="Public PORT of the hub"
).tag(config=True)

@observe('hub_port_connect')
def _port_connect_changed(self, change):
if jupyterhub.version_info >= (0, 8):
warnings.warn(
"MarathonSpawner.hub_port_connect is no longer needed with JupyterHub 0.8."
" Use JupyterHub.hub_connect_port instead.",
DeprecationWarning,
)

format_volume_name = Any(
help="""Any callable that accepts a string template and a Spawner
instance as parameters in that order and returns a string.
Expand All @@ -91,6 +112,16 @@ class MarathonSpawner(Spawner):
def _get_default_format_volume_name(self):
return default_format_volume_name

# fix default port to 8888, used in the container
@default('port')
def _port_default(self):
return 8888

# default to listening on all-interfaces in the container
@default('ip')
def _ip_default(self):
return '0.0.0.0'

_executor = None
@property
def executor(self):
Expand Down Expand Up @@ -122,7 +153,7 @@ def get_health_checks(self):
protocol='TCP',
port_index=0,
grace_period_seconds=300,
interval_seconds=60,
interval_seconds=30,
timeout_seconds=20,
max_consecutive_failures=0
))
Expand Down Expand Up @@ -201,25 +232,17 @@ def _public_hub_api_url(self):
uri.fragment
))

def get_env(self):
env = super(MarathonSpawner, self).get_env()
env.update(dict(
# Jupyter Hub config
JPY_USER=self.user.name,
JPY_COOKIE_NAME=self.user.server.cookie_name,
JPY_BASE_URL=self.user.server.base_url,
JPY_HUB_PREFIX=self.hub.server.base_url,
))

if self.notebook_dir:
env['NOTEBOOK_DIR'] = self.notebook_dir

if self.hub_ip_connect or self.hub_port_connect > 0:
hub_api_url = self._public_hub_api_url()
else:
hub_api_url = self.hub.api_url
env['JPY_HUB_API_URL'] = hub_api_url
return env
def get_args(self):
args = super().get_args()
if self.hub_ip_connect:
# JupyterHub 0.7 specifies --hub-api-url
# on the command-line, which is hard to update
for idx, arg in enumerate(list(args)):
if arg.startswith('--hub-api-url='):
args.pop(idx)
break
args.append('--hub-api-url=%s' % self._public_hub_api_url())
return args

@gen.coroutine
def start(self):
Expand All @@ -239,8 +262,10 @@ def start(self):
else:
mem_request = 1024.0

cmd = self.cmd + self.get_args()
app_request = MarathonApp(
id=self.container_name,
cmd=' '.join(cmd),
env=self.get_env(),
cpus=self.cpu_limit,
mem=mem_request,
Expand Down

0 comments on commit 79539ff

Please sign in to comment.