Skip to content

Commit

Permalink
Crash less when docker fails
Browse files Browse the repository at this point in the history
  • Loading branch information
avirshup committed Aug 24, 2017
1 parent 2e72c17 commit c3b75be
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 61 deletions.
2 changes: 1 addition & 1 deletion .dockerignore
Expand Up @@ -8,7 +8,7 @@
**/.ipynb_checkpoints
/build
*.egg-info
/dist
dist
**/.DS_Store
**/npm-debug.log
**/.cache/
Expand Down
27 changes: 0 additions & 27 deletions .travis.yml

This file was deleted.

Empty file added codeship-services.yml
Empty file.
Empty file added codeship-steps.yml
Empty file.
41 changes: 25 additions & 16 deletions nbmolviz/mdtconfig/docker.py
Expand Up @@ -23,8 +23,14 @@
from .images import DockerImageStatus


SPINNER = '<div class="nbv-loader" />'
CONNECTED = '<span style="color:green">connected</span>'
DISCONNECTED = '<span style="color:red">disconnected</span>'

class DockerConfig(VBox):
def __init__(self):
self.client = None
self.warning = ipy.HTML(description='<b>Engine status:</b>', value=SPINNER)
self.devmode_label = ipy.Label('Use local docker images (developer mode)',
layout=ipy.Layout(width='100%'))
self.devmode_button = ipy.Checkbox(value=mdt.compute.config.devmode,
Expand All @@ -40,31 +46,29 @@ def __init__(self):
self.engine_config_value = ipy.Text('blank', layout=ipy.Layout(width='100%'))
self.engine_config_value.add_class('nbv-monospace')

self.image_box = ipy.Box(children=(DockerImageStatus(),))
self.image_box = ipy.Box()

self._reset_config_button = ipy.Button(description='Reset',
tooltip='Reset to applied value')
self._apply_changes_button = ipy.Button(description='Apply',
tooltip='Apply for this session')
self._save_changes_button = ipy.Button(description='Make default',
tooltip='Make this the default for new sessions')
self._test_button = ipy.Button(description='Test connection',
tooltip='Test connection to docker engine')
self._reset_config_button.on_click(self.reset_config)
self._apply_changes_button.on_click(self.apply_config)
self._save_changes_button.on_click(self.save_config)
self._test_button.on_click(self.test_connection)

self.children = [VBox([self.engine_config_description,
self.children = [self.warning,
VBox([self.engine_config_description,
self.engine_config_value]),
HBox([self._reset_config_button,
self._apply_changes_button,
self._test_button,
self._save_changes_button]),
HBox([self.devmode_button, self.devmode_label]),
self.image_box]
self.reset_config()
super().__init__(children=self.children)
self.connect_to_engine()

def reset_config(self, *args):
""" Reset configuration in UI widget to the stored values
Expand All @@ -74,19 +78,24 @@ def reset_config(self, *args):
def set_devmode(self, *args):
self.image_box.children = ()
mdt.compute.config.devmode = self.devmode_button.value
self.image_box.children = (DockerImageStatus(),)
self.image_box.children = (DockerImageStatus(self.client),)

def apply_config(self, *args):
mdt.compute.config['default_docker_host'] = self.engine_config_value.value
mdt.compute.reset_compute_engine()

def test_connection(self, *args):
self.apply_config()
engine = mdt.compute.default_engine
if engine is None:
raise ValueError('Failed to create compute engine with current configuration')
engine.test_connection()
print("SUCCESS: %s is accepting jobs" % engine)
self.connect_to_engine()

def connect_to_engine(self, *args):
self.warning.value = SPINNER
self.client = None
try:
mdt.compute.reset_compute_engine()
self.client = mdt.compute.get_engine().client
self.client.ping()
except (mdt.exceptions.DockerError, AttributeError):
self.warning.value = DISCONNECTED
else:
self.image_box.children = (DockerImageStatus(self.client),)
self.warning.value = CONNECTED

def save_config(self, *args):
mdt.compute.update_saved_config(dockerhost=self.engine_config_value.value)
Expand Down
43 changes: 26 additions & 17 deletions nbmolviz/mdtconfig/images.py
Expand Up @@ -29,13 +29,14 @@


class DockerImageStatus(ipy.VBox):
def __init__(self):
def __init__(self, client):
self.client = client

images = self._get_images()
self.header = ipy.HTML(
'<span class="nbv-table-header" style="width:950px"">Image status</span>',
layout=ipy.Layout(align_items='flex-end'))
super().__init__([self.header] + [DockerImageView(im) for im in sorted(images)])
super().__init__([self.header] + [DockerImageView(im, client) for im in sorted(images)])

def _get_images(self):
return set(p.get_docker_image_path()
Expand All @@ -46,8 +47,9 @@ class DockerImageView(ipy.HBox):
LOADER = "<div class='nbv-loader' />"
DMKDIR = os.path.join(os.path.dirname(os.path.dirname(mdt.__file__)), 'DockerMakefiles')

def __init__(self, image):
def __init__(self, image, client):
self._err = False
self._client = client
self.image = image
self.status = ipy.HTML(layout=ipy.Layout(width="20px"))
self.html = ipy.HTML(value=image, layout=ipy.Layout(width="400px"))
Expand All @@ -59,7 +61,6 @@ def __init__(self, image):
else:
self.button.on_click(self.pull)
self._reactivate_button()
self._client = mdt.compute.get_engine().client
self._set_status_value()
super().__init__(children=[self.status, self.html, self.button, self.msg])

Expand Down Expand Up @@ -138,26 +139,34 @@ def _disable_button(self, description):

def _reactivate_button(self):
self.button.disabled = False
if mdt.compute.config.devmode:
self.button.description = 'Rebuild image'
if self._client is None:
self.button.description = 'no connection'
self.button.disabled = True
self.button.style.button_color = '#FAFAFA'
else:
self.button.description = 'Pull image'
self.button.style.font_weight = '400'
self.button.style.button_color = '#9feeb2'
if mdt.compute.config.devmode:
self.button.description = 'Rebuild image'
else:
self.button.description = 'Pull image'
self.button.style.font_weight = '400'
self.button.style.button_color = '#9feeb2'


def _set_status_value(self):
from docker import errors

try:
imginfo = self._client.inspect_image(self.image)
except errors.ImageNotFound:
if self._err:
self.status.value = WARNING
else:
self.status.value = MISSING
if self._client is None:
self.status.value = 'n/a'
else:
self.status.value = INSTALLED
try:
imginfo = self._client.inspect_image(self.image)
except errors.ImageNotFound:
if self._err:
self.status.value = WARNING
else:
self.status.value = MISSING
else:
self.status.value = INSTALLED

def _watch_pull_logs(self, stream):
found = set()
Expand Down

0 comments on commit c3b75be

Please sign in to comment.