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:
parent
648aa26d55
commit
3070012c3e
|
@ -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'},
|
||||
|
|
|
@ -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))
|
|
@ -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))
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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',
|
||||
|
|
Loading…
Reference in New Issue