Add bay_uuid attribute to Container model
partially implements blueprint docker-conductor-connect-to-docker-bay Change-Id: Ied85b4e2a69369ed39be3549e743fd0ea30f13a5
This commit is contained in:
parent
552879b6a9
commit
14ff11c017
|
@ -36,7 +36,10 @@ LOG = logging.getLogger(__name__)
|
|||
|
||||
|
||||
class ContainerPatchType(types.JsonPatchType):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def mandatory_attrs():
|
||||
return ['/bay_uuid']
|
||||
|
||||
|
||||
class Container(base.APIBase):
|
||||
|
@ -47,6 +50,24 @@ class Container(base.APIBase):
|
|||
container.
|
||||
"""
|
||||
|
||||
_bay_uuid = None
|
||||
|
||||
def _get_bay_uuid(self):
|
||||
return self._bay_uuid
|
||||
|
||||
def _set_bay_uuid(self, value):
|
||||
if value and self._bay_uuid != value:
|
||||
try:
|
||||
bay = objects.Bay.get_by_uuid(pecan.request.context, value)
|
||||
self._bay_uuid = bay['uuid']
|
||||
except exception.BayNotFound as e:
|
||||
# Change error code because 404 (NotFound) is inappropriate
|
||||
# response for a POST request to create a Service
|
||||
e.code = 400 # BadRequest
|
||||
raise e
|
||||
elif value == wtypes.Unset:
|
||||
self._bay_uuid = wtypes.Unset
|
||||
|
||||
uuid = types.uuid
|
||||
"""Unique UUID for this container"""
|
||||
|
||||
|
@ -56,6 +77,10 @@ class Container(base.APIBase):
|
|||
image_id = wtypes.text
|
||||
"""The image name or UUID to use as a base image for this baymodel"""
|
||||
|
||||
bay_uuid = wsme.wsproperty(types.uuid, _get_bay_uuid, _set_bay_uuid,
|
||||
mandatory=True)
|
||||
"""Unique UUID of the bay this runs on"""
|
||||
|
||||
links = wsme.wsattr([link.Link], readonly=True)
|
||||
"""A list containing a self link and associated container links"""
|
||||
|
||||
|
@ -74,7 +99,7 @@ class Container(base.APIBase):
|
|||
@staticmethod
|
||||
def _convert_with_links(container, url, expand=True):
|
||||
if not expand:
|
||||
container.unset_fields_except(['uuid', 'name',
|
||||
container.unset_fields_except(['uuid', 'name', 'bay_uuid',
|
||||
'image_id', 'command'])
|
||||
|
||||
container.links = [link.Link.make_link('self', url,
|
||||
|
@ -97,6 +122,7 @@ class Container(base.APIBase):
|
|||
name='example',
|
||||
image_id='ubuntu',
|
||||
command='env',
|
||||
bay_uuid="fff114da-3bfa-4a0f-a123-c0dffad9718e",
|
||||
created_at=datetime.datetime.utcnow(),
|
||||
updated_at=datetime.datetime.utcnow())
|
||||
return cls._convert_with_links(sample, 'http://localhost:9511', expand)
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
# 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.
|
||||
|
||||
"""add bay uuid
|
||||
|
||||
Revision ID: 2d8657c0cdc
|
||||
Revises: e772b2598d9
|
||||
Create Date: 2015-04-22 16:59:06.799384
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '2d8657c0cdc'
|
||||
down_revision = 'e772b2598d9'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.add_column('container', sa.Column('bay_uuid',
|
||||
sa.String(length=255), nullable=True))
|
|
@ -185,6 +185,7 @@ class Container(Base):
|
|||
name = Column(String(255))
|
||||
image_id = Column(String(255))
|
||||
command = Column(String(255))
|
||||
bay_uuid = Column(String(36))
|
||||
|
||||
|
||||
class Node(Base):
|
||||
|
|
|
@ -32,6 +32,7 @@ class Container(base.MagnumObject):
|
|||
'user_id': obj_utils.str_or_none,
|
||||
'image_id': obj_utils.str_or_none,
|
||||
'command': obj_utils.str_or_none,
|
||||
'bay_uuid': obj_utils.str_or_none,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
|
|
|
@ -9,13 +9,17 @@
|
|||
# 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.
|
||||
|
||||
from magnum import objects
|
||||
from magnum.tests.unit.db import base as db_base
|
||||
from magnum.tests.unit.db import utils
|
||||
|
||||
from mock import patch
|
||||
from webtest.app import AppError
|
||||
|
||||
|
||||
class TestContainerController(db_base.DbTestCase):
|
||||
@patch('magnum.objects.bay.Bay.get_by_uuid')
|
||||
@patch('magnum.conductor.api.API.container_create')
|
||||
@patch('magnum.conductor.api.API.container_delete')
|
||||
@patch('magnum.conductor.api.API.container_start')
|
||||
|
@ -34,7 +38,8 @@ class TestContainerController(db_base.DbTestCase):
|
|||
mock_container_stop,
|
||||
mock_container_start,
|
||||
mock_container_delete,
|
||||
mock_container_create):
|
||||
mock_container_create,
|
||||
mock_get_by_uuid):
|
||||
mock_container_create.side_effect = lambda x, y, z: z
|
||||
mock_container_start.return_value = None
|
||||
mock_container_stop.return_value = None
|
||||
|
@ -45,7 +50,14 @@ class TestContainerController(db_base.DbTestCase):
|
|||
mock_container_execute.return_value = None
|
||||
|
||||
# Create a container
|
||||
params = '{"name": "My Docker", "image_id": "ubuntu"}'
|
||||
params = ('{"name": "My Docker", "image_id": "ubuntu",'
|
||||
'"command": "env",'
|
||||
'"bay_uuid": "fff114da-3bfa-4a0f-a123-c0dffad9718e"}')
|
||||
self.fake_bay = utils.get_test_bay()
|
||||
value = self.fake_bay['uuid']
|
||||
mock_get_by_uuid.return_value = self.fake_bay
|
||||
bay = objects.Bay.get_by_uuid(self.context, value)
|
||||
self.assertEqual(value, bay['uuid'])
|
||||
response = self.app.post('/v1/containers',
|
||||
params=params,
|
||||
content_type='application/json')
|
||||
|
@ -106,20 +118,65 @@ class TestContainerController(db_base.DbTestCase):
|
|||
c = response.json['containers']
|
||||
self.assertEqual(0, len(c))
|
||||
|
||||
@patch('magnum.objects.bay.Bay.get_by_uuid')
|
||||
@patch('magnum.conductor.api.API.container_create')
|
||||
@patch('magnum.conductor.api.API.container_delete')
|
||||
def test_create_container_with_command(self,
|
||||
mock_container_delete,
|
||||
mock_container_create):
|
||||
mock_container_create,
|
||||
mock_get_by_uuid):
|
||||
mock_container_create.side_effect = lambda x, y, z: z
|
||||
# Create a container with a command
|
||||
params = ('{"name": "My Docker", "image_id": "ubuntu",'
|
||||
'"command": "env"}')
|
||||
'"command": "env",'
|
||||
'"bay_uuid": "fff114da-3bfa-4a0f-a123-c0dffad9718e"}')
|
||||
self.fake_bay = utils.get_test_bay()
|
||||
value = self.fake_bay['uuid']
|
||||
mock_get_by_uuid.return_value = self.fake_bay
|
||||
bay = objects.Bay.get_by_uuid(self.context, value)
|
||||
self.assertEqual(value, bay['uuid'])
|
||||
response = self.app.post('/v1/containers',
|
||||
params=params,
|
||||
content_type='application/json')
|
||||
self.assertEqual(response.status_int, 201)
|
||||
# get all containers
|
||||
response = self.app.get('/v1/containers')
|
||||
self.assertEqual(response.status_int, 200)
|
||||
self.assertEqual(1, len(response.json))
|
||||
c = response.json['containers'][0]
|
||||
self.assertIsNotNone(c.get('uuid'))
|
||||
self.assertEqual('My Docker', c.get('name'))
|
||||
self.assertEqual('env', c.get('command'))
|
||||
# Delete the container we created
|
||||
response = self.app.delete('/v1/containers/%s' % c.get('uuid'))
|
||||
self.assertEqual(response.status_int, 204)
|
||||
|
||||
response = self.app.get('/v1/containers')
|
||||
self.assertEqual(response.status_int, 200)
|
||||
c = response.json['containers']
|
||||
self.assertEqual(0, len(c))
|
||||
|
||||
@patch('magnum.objects.bay.Bay.get_by_uuid')
|
||||
@patch('magnum.conductor.api.API.container_create')
|
||||
@patch('magnum.conductor.api.API.container_delete')
|
||||
def test_create_container_with_bay_uuid(self,
|
||||
mock_container_delete,
|
||||
mock_container_create,
|
||||
mock_get_by_uuid):
|
||||
mock_container_create.side_effect = lambda x, y, z: z
|
||||
# Create a container with a command
|
||||
params = ('{"name": "My Docker", "image_id": "ubuntu",'
|
||||
'"command": "env",'
|
||||
'"bay_uuid": "fff114da-3bfa-4a0f-a123-c0dffad9718e"}')
|
||||
self.fake_bay = utils.get_test_bay()
|
||||
value = self.fake_bay['uuid']
|
||||
mock_get_by_uuid.return_value = self.fake_bay
|
||||
bay = objects.Bay.get_by_uuid(self.context, value)
|
||||
self.assertEqual(value, bay['uuid'])
|
||||
response = self.app.post('/v1/containers',
|
||||
params=params,
|
||||
content_type='application/json')
|
||||
self.assertEqual(response.status_int, 201)
|
||||
|
||||
# get all containers
|
||||
response = self.app.get('/v1/containers')
|
||||
self.assertEqual(response.status_int, 200)
|
||||
|
|
|
@ -183,6 +183,7 @@ def get_test_container(**kw):
|
|||
'created_at': kw.get('created_at'),
|
||||
'updated_at': kw.get('updated_at'),
|
||||
'command': kw.get('command', 'fake_command'),
|
||||
'bay_uuid': kw.get('bay_uuid', 'fff114da-3bfa-4a0f-a123-c0dffad9718e'),
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue