From 8bcf73fda632d5f3641cb1774cac1a0f643e20de Mon Sep 17 00:00:00 2001 From: prameswar Date: Fri, 6 Jan 2017 14:20:07 +0530 Subject: [PATCH] Added zun exec state validation Command zun exec ... returning 500 if the container is not 'Running'. It should return 400 or 409 instead. The reason of this failure is because we missed a validation entry for "exec" entry. Closes-Bug: #1654391 Change-Id: I20e4dc19f6b1a76a002f5ff1ec4ddd05bf8311f4 --- zun/compute/manager.py | 2 ++ zun/tests/unit/compute/test_compute_manager.py | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/zun/compute/manager.py b/zun/compute/manager.py index bb41d0a05..00d784ce7 100644 --- a/zun/compute/manager.py +++ b/zun/compute/manager.py @@ -37,6 +37,7 @@ VALID_STATES = { 'pause': ['Running'], 'unpause': ['Paused'], 'kill': ['Running'], + 'exec': ['Running'], } @@ -315,6 +316,7 @@ class Manager(object): # TODO(hongbin): support exec command interactively LOG.debug('Executing command in container: %s', container.uuid) try: + self._validate_container_state(container, 'exec') return self.driver.execute(container, command) except exception.DockerError as e: LOG.error(_LE("Error occurred while calling docker exec API: %s"), diff --git a/zun/tests/unit/compute/test_compute_manager.py b/zun/tests/unit/compute/test_compute_manager.py index be89d1cfd..e92ab5eea 100644 --- a/zun/tests/unit/compute/test_compute_manager.py +++ b/zun/tests/unit/compute/test_compute_manager.py @@ -65,6 +65,9 @@ class TestManager(base.TestCase): container.status = 'Stopped' self.assertIsNone(self.compute_manager._validate_container_state( container, 'reboot')) + container.status = 'Running' + self.assertIsNone(self.compute_manager._validate_container_state( + container, 'exec')) @mock.patch.object(Container, 'save') @mock.patch('zun.image.driver.pull_image') @@ -411,6 +414,14 @@ class TestManager(base.TestCase): self.context, container, 'fake_cmd') mock_execute.assert_called_once_with(container, 'fake_cmd') + @mock.patch.object(manager.Manager, '_validate_container_state') + def test_container_execute_invalid_state(self, mock_validate): + container = Container(self.context, **utils.get_test_container()) + mock_validate.side_effect = exception.InvalidStateException + self.assertRaises(exception.InvalidStateException, + self.compute_manager.container_exec, + self.context, container, 'fake_cmd') + @mock.patch.object(fake_driver, 'execute') def test_container_execute_failed(self, mock_execute): container = Container(self.context, **utils.get_test_container())