Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions remoteappmanager/docker/docker_labels.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,7 @@ def __init__(self, namespace, labels):
# "vncapp", "webapp" or not present (for legacy apps). This will
# affect the configurability of the image at startup.
"type",
# environment variables that the container accepts.
# This is a sub-namespace. It will hold keys itself.
"env",
])
30 changes: 27 additions & 3 deletions remoteappmanager/docker/image.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import string
from traitlets import Unicode, HasTraits, Dict

from remoteappmanager.docker.docker_labels import SIMPHONY_NS
from traitlets import Unicode, HasTraits

# Characters that are allowed in the environment variables.
_ALLOWED_ENVCHARS = set(string.ascii_lowercase + string.digits + "-")


class Image(HasTraits):
Expand All @@ -21,10 +26,17 @@ class Image(HasTraits):
#: A long description of the image.
description = Unicode()

#: The type of the image. This allows to differentiate image behavior
#: once started.
#: The type of the image.
type = Unicode()

# A dictionary of supported environment variables that the
# container can accept as parameters. Note that the labels
# use a different notation, so a conversion takes place:
# dashes are converted to underscores, and letters are capitalized.
# e.g. x11-width -> X11_WIDTH
# Only keys are used at the moment.
env = Dict()

@classmethod
def from_docker_dict(cls, docker_dict):
"""Converts the dict response from the dockerpy library into an
Expand Down Expand Up @@ -53,4 +65,16 @@ def from_docker_dict(cls, docker_dict):
self.description = labels.get(SIMPHONY_NS.description, '')
self.type = labels.get(SIMPHONY_NS.type, '')

env_prefix = SIMPHONY_NS.env+"."
for env in [lab[len(env_prefix):]
for lab in labels.keys()
if lab.startswith(env_prefix)]:

if len(set(env) - _ALLOWED_ENVCHARS) != 0:
# Skip badly formed stuff.
continue

env = env.upper().replace("-", "_")
self.env[env] = None

return self
7 changes: 7 additions & 0 deletions remoteappmanager/docker/tests/test_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ def test_from_docker_dict_images(self):
def test_from_docker_dict_inspect_image(self):
docker_client = create_docker_client()
image_dict = docker_client.inspect_image('image_id1')

labels = image_dict['Config']['Labels']
# Insert an unpalatable label for the envs.
labels['eu.simphony-project.docker.env.x11-height.whatever'] = None

image = Image.from_docker_dict(image_dict)

self.assertEqual(image.docker_id, image_dict["Id"])
Expand All @@ -34,10 +39,12 @@ def test_from_docker_dict_inspect_image(self):
image.ui_name,
image_dict['Config']["Labels"][SIMPHONY_NS.ui_name])
self.assertEqual(image.type, 'vncapp')
self.assertEqual(image.env, {"X11_WIDTH": None})

def test_missing_image_type(self):
docker_client = create_docker_client()
image_dict = docker_client.inspect_image('image_id2')
image = Image.from_docker_dict(image_dict)

self.assertEqual(image.type, '')
self.assertEqual(image.env, {})
1 change: 1 addition & 0 deletions remoteappmanager/tests/mocking/virtual/docker_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def get_fake_image_labels(num=2):
{'eu.simphony-project.docker.description': 'Ubuntu machine with mayavi preinstalled', # noqa
'eu.simphony-project.docker.ui_name': 'Mayavi 4.4.4',
'eu.simphony-project.docker.type': 'vncapp',
'eu.simphony-project.docker.env.x11-width': None,
},
{'eu.simphony-project.docker.description': 'A vanilla Ubuntu installation'}, # noqa
)
Expand Down