Add status_reason column to 'container' table

This patch adds status_reason column to container
database, so that user can get the reason for
errors and failures of container operation. I
will add the code to populate this field in next
patch.

Closes-Bug: #1634760
Change-Id: I5a62e873df60ccdd7dbf9b7b0351d7e064378902
This commit is contained in:
Pradeep Kumar Singh 2016-10-28 08:01:23 +00:00
parent 648aa26d55
commit 3070012c3e
7 changed files with 83 additions and 0 deletions

View File

@ -83,6 +83,9 @@ class Container(base.APIBase):
'max_length': 255,
},
},
'status_reason': {
'validate': types.Text.validate,
},
'task_state': {
'validate': types.String.validate,
'validate_args': {
@ -151,6 +154,7 @@ class Container(base.APIBase):
image='ubuntu',
command='env',
status='Running',
status_reason='',
cpu=1.0,
memory='512m',
environment={'key1': 'val1', 'key2': 'val2'},

View File

@ -0,0 +1,35 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Insert status_reason to Container table
Revision ID: c5565cbaa3de
Revises: 72c6947c6636
Create Date: 2016-10-28 06:51:12.146721
"""
# revision identifiers, used by Alembic.
revision = 'c5565cbaa3de'
down_revision = '72c6947c6636'
branch_labels = None
depends_on = None
from alembic import op
import sqlalchemy as sa
def upgrade():
op.add_column('container',
sa.Column('status_reason', sa.Text(),
nullable=True))

View File

@ -27,6 +27,7 @@ from sqlalchemy import Float
from sqlalchemy import Integer
from sqlalchemy import schema
from sqlalchemy import String
from sqlalchemy import Text
from sqlalchemy.types import TypeDecorator, TEXT
@ -133,6 +134,7 @@ class Container(Base):
command = Column(String(255))
memory = Column(String(255))
status = Column(String(20))
status_reason = Column(Text, nullable=True)
task_state = Column(String(20))
environment = Column(JSONEncodedDict)
workdir = Column(String(255))

View File

@ -39,6 +39,7 @@ class Container(base.ZunPersistentObject, base.ZunObject,
'memory': fields.StringField(nullable=True),
'command': fields.StringField(nullable=True),
'status': z_fields.ContainerStatusField(nullable=True),
'status_reason': fields.StringField(nullable=True),
'task_state': z_fields.TaskStateField(nullable=True),
'environment': fields.DictOfStringsField(nullable=True),
'workdir': fields.StringField(nullable=True),

View File

@ -53,6 +53,20 @@ class TestContainerController(api_base.FunctionalTest):
params=params,
content_type='application/json')
@patch('zun.compute.api.API.container_create')
def test_create_container_resp_has_status_reason(self,
mock_container_create):
mock_container_create.side_effect = lambda x, y: y
# Create a container with a command
params = ('{"name": "My Docker", "image": "ubuntu",'
'"command": "env", "memory": "512m",'
'"environment": {"key1": "val1", "key2": "val2"}}')
response = self.app.post('/v1/containers/',
params=params,
content_type='application/json')
self.assertEqual(202, response.status_int)
self.assertIn('status_reason', response.json.keys())
@patch('zun.compute.api.API.container_show')
@patch('zun.compute.api.API.container_create')
@patch('zun.compute.api.API.container_delete')
@ -210,6 +224,23 @@ class TestContainerController(api_base.FunctionalTest):
self.assertEqual(test_container['uuid'],
actual_containers[0].get('uuid'))
@patch('zun.compute.api.API.container_show')
@patch('zun.objects.Container.list')
def test_get_all_has_status_reason(self, mock_container_list,
mock_container_show):
test_container = utils.get_test_container()
containers = [objects.Container(self.context, **test_container)]
mock_container_list.return_value = containers
mock_container_show.return_value = containers[0]
response = self.app.get('/v1/containers/')
self.assertEqual(200, response.status_int)
actual_containers = response.json['containers']
self.assertEqual(1, len(actual_containers))
self.assertEqual(test_container['uuid'],
actual_containers[0].get('uuid'))
self.assertIn('status_reason', actual_containers[0].keys())
@patch('zun.compute.api.API.container_show')
@patch('zun.objects.Container.list')
def test_get_all_containers_with_pagination_marker(self,

View File

@ -29,6 +29,7 @@ def get_test_container(**kw):
'updated_at': kw.get('updated_at'),
'command': kw.get('command', 'fake_command'),
'status': kw.get('status', 'Running'),
'status_reason': kw.get('status_reason', 'Created Successfully'),
'task_state': kw.get('task_state', 'container_creating'),
'environment': kw.get('environment', {'key1': 'val1', 'key2': 'val2'}),
'cpu': kw.get('cpu', 1.0),

View File

@ -92,6 +92,15 @@ class TestContainerObject(base.DbTestCase):
mock_create_container.assert_called_once_with(self.fake_container)
self.assertEqual(self.context, container._context)
def test_status_reason_in_fields(self):
container = objects.Container(self.context, **self.fake_container)
self.assertTrue(hasattr(container, 'status_reason'))
container.status_reason = "Docker Error happened"
container.create()
containers = objects.Container.list(self.context)
self.assertTrue(hasattr(containers[0], 'status_reason'))
self.assertEqual("Docker Error happened", containers[0].status_reason)
def test_destroy(self):
uuid = self.fake_container['uuid']
with mock.patch.object(self.dbapi, 'get_container_by_uuid',