diff --git a/remoteappmanager/docker/docker_labels.py b/remoteappmanager/docker/docker_labels.py index c2a757696..0fda355dd 100644 --- a/remoteappmanager/docker/docker_labels.py +++ b/remoteappmanager/docker/docker_labels.py @@ -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", ]) diff --git a/remoteappmanager/docker/image.py b/remoteappmanager/docker/image.py index 2a6e88fb1..8e6d64557 100644 --- a/remoteappmanager/docker/image.py +++ b/remoteappmanager/docker/image.py @@ -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): @@ -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 @@ -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 diff --git a/remoteappmanager/docker/tests/test_image.py b/remoteappmanager/docker/tests/test_image.py index a863594ed..129d33853 100644 --- a/remoteappmanager/docker/tests/test_image.py +++ b/remoteappmanager/docker/tests/test_image.py @@ -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"]) @@ -34,6 +39,7 @@ 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() @@ -41,3 +47,4 @@ def test_missing_image_type(self): image = Image.from_docker_dict(image_dict) self.assertEqual(image.type, '') + self.assertEqual(image.env, {}) diff --git a/remoteappmanager/tests/mocking/virtual/docker_client.py b/remoteappmanager/tests/mocking/virtual/docker_client.py index e0ccb5b6a..6a8a339f4 100644 --- a/remoteappmanager/tests/mocking/virtual/docker_client.py +++ b/remoteappmanager/tests/mocking/virtual/docker_client.py @@ -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 )