Repository: simphony/simphony-remote

Issue:
Image's ui_name are no longer shown
Docker images with a `ui_name` label no longer has its name shown on the home page of the singleuser app.
It is a retrogression.

Discussion:

Patch:
diff --git a/remoteappmanager/docker/image.py b/remoteappmanager/docker/image.py
index 5413320..85262a6 100644
--- a/remoteappmanager/docker/image.py
+++ b/remoteappmanager/docker/image.py
@@ -24,7 +24,14 @@ class Image(HasTraits):
     @classmethod
     def from_docker_dict(cls, docker_dict):
         """Converts the dict response from the dockerpy library into an
-        instance of this class, extracting the relevant information."""
+        instance of this class, extracting the relevant information.
+
+        Parameters
+        ----------
+        docker_dict : dict
+           Results of `docker.client.inspect_image` or an item of the
+           result of `docker.client.images`
+        """
         self = cls()
         self.docker_id = docker_dict["Id"]
 
@@ -33,7 +40,9 @@ class Image(HasTraits):
         except (KeyError, IndexError):
             self.name = ''
 
-        labels = docker_dict.get("Labels")
+        labels = (docker_dict.get("Labels") or
+                  docker_dict.get("Config", {}).get("Labels"))
+
         if labels is not None:
             self.ui_name = labels.get(docker_labels.UI_NAME, '')
             self.icon_128 = labels.get(docker_labels.ICON_128, '')


Test patch:
diff --git a/tests/docker/test_container_manager.py b/tests/docker/test_container_manager.py
index 0dc216d..7610825 100644
--- a/tests/docker/test_container_manager.py
+++ b/tests/docker/test_container_manager.py
@@ -108,7 +108,7 @@ class TestContainerManager(AsyncTestCase):
         self.assertEqual(image.description,
                          'Ubuntu machine with mayavi preinstalled')
         self.assertEqual(image.icon_128, "")
-        self.assertEqual(image.ui_name, "")
+        self.assertEqual(image.ui_name, "Mayavi 4.4.4")
         self.assertEqual(image.docker_id,
                          'sha256:e54d71dde57576e9d2a4c77ce0c98501c8aa6268de5b2987e4c80e2e157cffe4')  # noqa
 
diff --git a/tests/docker/test_image.py b/tests/docker/test_image.py
index 29cc03d..c21733f 100644
--- a/tests/docker/test_image.py
+++ b/tests/docker/test_image.py
@@ -6,12 +6,28 @@ from tests.utils import mock_docker_client
 
 
 class TestImage(TestCase):
-    def test_from_docker_dict(self):
+    def test_from_docker_dict_images(self):
         docker_client = mock_docker_client()
-        images = docker_client.images()
-        image = Image.from_docker_dict(images[0])
+        image_dict = docker_client.images()[0]
+        image = Image.from_docker_dict(image_dict)
 
-        self.assertEqual(image.docker_id, images[0]["Id"])
-        self.assertEqual(image.name, images[0]["RepoTags"][0])
+        self.assertEqual(image.docker_id, image_dict["Id"])
+        self.assertEqual(image.name, image_dict["RepoTags"][0])
         self.assertEqual(image.description,
-                         images[0]["Labels"][docker_labels.DESCRIPTION])
+                         image_dict["Labels"][docker_labels.DESCRIPTION])
+        self.assertEqual(image.ui_name,
+                         image_dict["Labels"][docker_labels.UI_NAME])
+
+    def test_from_docker_dict_inspect_image(self):
+        docker_client = mock_docker_client()
+        image_dict = docker_client.inspect_image()
+        image = Image.from_docker_dict(image_dict)
+
+        self.assertEqual(image.docker_id, image_dict["Id"])
+        self.assertEqual(image.name, image_dict["RepoTags"][0])
+        self.assertEqual(
+            image.description,
+            image_dict['Config']["Labels"][docker_labels.DESCRIPTION])
+        self.assertEqual(
+            image.ui_name,
+            image_dict['Config']["Labels"][docker_labels.UI_NAME])
diff --git a/tests/utils.py b/tests/utils.py
index d35f7e9..2a6a5d7 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -13,19 +13,36 @@ def mock_docker_client():
     """Returns a mock synchronous docker client to return canned
     responses."""
     docker_client = mock.Mock(spec=docker.Client)
+
+    # Note that the structure of the returned dictionary is different
+    # for `inspect_image` and for `images`
+    # The return value is simplified...
     docker_client.inspect_image = mock.Mock(
-        return_value={'Created': 1463662803,
-                      'Id':
-                          'sha256:e54d71dde57576e9d2a4c77ce0c98501c8aa6268de5b2987e4c80e2e157cffe4',  # noqa
-                      'Labels': {
-                        'eu.simphony-project.docker.description':
-                            'Ubuntu machine with mayavi preinstalled'
-                      },
-                      'ParentId': 'sha256:d2f7240076e135f6aba57185e54ff45cc158781c787897b67994f72fe668ad07',  # noqa
-                      'RepoDigests': None,
-                      'RepoTags': ['simphony/mayavi-4.4.4:latest'],
-                      'Size': 1094833658,
-                      'VirtualSize': 1094833658})
+        return_value= {
+            'Author': 'SimPhoNy Team',
+            'Comment': '',
+            'Config': {'Cmd': None,
+                       'Domainname': '',
+                       'Entrypoint': ['/startup.sh'],
+                       'Env': ['PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
+                               'DEBIAN_FRONTEND=noninteractive',
+                               'HOME=/root'],
+                       'ExposedPorts': {'8888/tcp': {}},
+                       'Hostname': 'dfc2eabdf236',
+                       'Image': 'sha256:912b31a4e4f185b918999540040bb158e208ce0123fde4be07c188b2ab5aa4bb',
+                       'Labels': {'eu.simphony-project.docker.description': 'Ubuntu machine with mayavi preinstalled',  # noqa
+                                  'eu.simphony-project.docker.ui_name': 'Mayavi 4.4.4'},  # noqa
+                       'OnBuild': [],
+                       'OpenStdin': False,
+                       'StdinOnce': False,
+                       'Tty': False,
+                       'User': '',
+                       'Volumes': None,
+                       'WorkingDir': '/root'},
+            'Id': 'sha256:e54d71dde57576e9d2a4c77ce0c98501c8aa6268de5b2987e4c80e2e157cffe4',
+            'RepoTags': ['simphony/mayavi-4.4.4:latest'],
+            'Size': 668483801,
+            'VirtualSize': 668483801})
     docker_client.inspect_container = mock.Mock(return_value=None)
     docker_client.create_host_config = mock.Mock(return_value={})
     docker_client.create_container = mock.Mock(
@@ -41,7 +58,8 @@ def mock_docker_client():
             {'Created': 1463662803,
              'Id': 'sha256:e54d71dde57576e9d2a4c77ce0c98501c8aa6268de5b2987e4c80e2e157cffe4',  # noqa
              'Labels': {
-             'eu.simphony-project.docker.description': 'Ubuntu machine with mayavi preinstalled'  # noqa
+                 'eu.simphony-project.docker.description': 'Ubuntu machine with mayavi preinstalled',  # noqa
+                 'eu.simphony-project.docker.ui_name': 'Mayavi 4.4.4'  # noqa
              },
             'ParentId': 'sha256:d2f7240076e135f6aba57185e54ff45cc158781c787897b67994f72fe668ad07',  # noqa
             'RepoDigests': None,