[lxc-devel] [pylxd/master] Container creation failure handling

jpic on Github lxc-bot at linuxcontainers.org
Mon May 23 13:25:59 UTC 2016


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 510 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20160523/afd63660/attachment.bin>
-------------- next part --------------
From fe71bc3a1b6da02d0ec7f4fb70baa48796fb90b9 Mon Sep 17 00:00:00 2001
From: jpic <jamespic at gmail.com>
Date: Thu, 19 May 2016 13:13:36 +0200
Subject: [PATCH 1/5] status is a string now

---
 integration/test_containers.py | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/integration/test_containers.py b/integration/test_containers.py
index d72d4fb..2a00121 100644
--- a/integration/test_containers.py
+++ b/integration/test_containers.py
@@ -98,15 +98,15 @@ def test_start_stop(self):
         # to test what we need.
         self.container.start(wait=True)
 
-        self.assertEqual('Running', self.container.status['status'])
+        self.assertEqual('Running', self.container.status)
         container = self.client.containers.get(self.container.name)
-        self.assertEqual('Running', container.status['status'])
+        self.assertEqual('Running', container.status)
 
         self.container.stop(wait=True)
 
-        self.assertEqual('Stopped', self.container.status['status'])
+        self.assertEqual('Stopped', self.container.status)
         container = self.client.containers.get(self.container.name)
-        self.assertEqual('Stopped', container.status['status'])
+        self.assertEqual('Stopped', container.status)
 
     def test_snapshot(self):
         """A container snapshot is made, renamed, and deleted."""

From aaa5fccd6479b3b742d9158b04f936d8c403965a Mon Sep 17 00:00:00 2001
From: jpic <jamespic at gmail.com>
Date: Thu, 19 May 2016 13:14:26 +0200
Subject: [PATCH 2/5] Make architecture a string type

Fixes:

    {u'type': u'error', u'error_code': 400, u'error': u'json: cannot unmarshal number into Go value of type string'}
---
 integration/test_containers.py | 2 +-
 integration/testing.py         | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/integration/test_containers.py b/integration/test_containers.py
index 2a00121..cb0086d 100644
--- a/integration/test_containers.py
+++ b/integration/test_containers.py
@@ -40,7 +40,7 @@ def test_create(self):
         """Creates and returns a new container."""
         config = {
             'name': 'an-container',
-            'architecture': 2,
+            'architecture': '2',
             'profiles': ['default'],
             'ephemeral': True,
             'config': {'limits.cpu': '2'},
diff --git a/integration/testing.py b/integration/testing.py
index e6e3cfe..ba2d1da 100644
--- a/integration/testing.py
+++ b/integration/testing.py
@@ -37,7 +37,7 @@ def create_container(self):
         name = self.generate_object_name()
         machine = {
             'name': name,
-            'architecture': 2,
+            'architecture': '2',
             'profiles': ['default'],
             'ephemeral': False,
             'config': {'limits.cpu': '2'},

From b381a70f50f5ae87a44124b8dfed71f3e74258c8 Mon Sep 17 00:00:00 2001
From: jpic <jamespic at gmail.com>
Date: Thu, 19 May 2016 13:17:33 +0200
Subject: [PATCH 3/5] Expect test to have created 1 container

---
 integration/test_containers.py | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/integration/test_containers.py b/integration/test_containers.py
index cb0086d..50d40ed 100644
--- a/integration/test_containers.py
+++ b/integration/test_containers.py
@@ -28,12 +28,17 @@ def test_get(self):
 
     def test_all(self):
         """A list of all containers is returned."""
+        containers_before_create = self.client.containers.all()
+
         name = self.create_container()
         self.addCleanup(self.delete_container, name)
 
         containers = self.client.containers.all()
 
-        self.assertEqual(1, len(containers))
+        self.assertEqual(
+            len(containers_before_create) + 1,
+            len(containers)
+        )
         self.assertEqual(name, containers[0].name)
 
     def test_create(self):

From 73341deea477c9b043ddec02db6c95f8e88fb5db Mon Sep 17 00:00:00 2001
From: jpic <jamespic at gmail.com>
Date: Thu, 19 May 2016 13:40:58 +0200
Subject: [PATCH 4/5] Setup LXD before running integration tests

The busybox image is necessary for test_containers.
---
 tox.ini | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/tox.ini b/tox.ini
index c90612f..55394f8 100644
--- a/tox.ini
+++ b/tox.ini
@@ -16,7 +16,11 @@ commands = nosetests pylxd
 commands = flake8
 
 [testenv:integration]
-commands = nosetests integration
+passenv = HOME
+whitelist_externals = lxc
+commands =
+    lxc image import https://dl.stgraber.org/lxd --alias busybox
+    nosetests integration
 
 [flake8]
 # E123, E125 skipped as they are invalid PEP-8.

From 4132dd5bcf9f225cbd49b16e13c25150b093df78 Mon Sep 17 00:00:00 2001
From: jpic <jamespic at gmail.com>
Date: Mon, 23 May 2016 15:22:25 +0200
Subject: [PATCH 5/5] Handle container creation failure

---
 integration/test_containers.py | 9 +++++++++
 pylxd/container.py             | 8 +++++++-
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/integration/test_containers.py b/integration/test_containers.py
index 50d40ed..f4974fd 100644
--- a/integration/test_containers.py
+++ b/integration/test_containers.py
@@ -13,6 +13,8 @@
 #    under the License.
 from integration.testing import IntegrationTestCase
 
+from pylxd.exceptions import ContainerCreationFailure
+
 
 class TestContainers(IntegrationTestCase):
     """Tests for `Client.containers`"""
@@ -58,6 +60,13 @@ def test_create(self):
 
         self.assertEqual(config['name'], container.name)
 
+    def test_create_failure(self):
+        with self.assertRaises(ContainerCreationFailure) as e:
+            container = self.client.containers.create(dict(name=self.id()))
+
+        # Check that we have the response object
+        self.assertEqual(e.exception.response.status_code, 400)
+
 
 class TestContainer(IntegrationTestCase):
     """Tests for Client.Container."""
diff --git a/pylxd/container.py b/pylxd/container.py
index 38bbe04..ba2b3dd 100644
--- a/pylxd/container.py
+++ b/pylxd/container.py
@@ -16,6 +16,7 @@
 
 from pylxd import mixin
 from pylxd.containerState import ContainerState
+from pylxd.exceptions import ContainerCreationFailure
 from pylxd.operation import Operation
 
 
@@ -64,8 +65,13 @@ def create(cls, client, config, wait=False):
         """Create a new container config."""
         response = client.api.containers.post(json=config)
 
+        data = response.json()
+
+        if data.get('type', None) == 'error':
+            raise ContainerCreationFailure(response)
+
         if wait:
-            Operation.wait_for_operation(client, response.json()['operation'])
+            Operation.wait_for_operation(client, data['operation'])
         return cls(name=config['name'])
 
     def __init__(self, **kwargs):


More information about the lxc-devel mailing list