Rename image_id to image in container object
Currently, magnum used "image_id" to reflect the image in container, but actually, we can support use both image name and image id to create a container. The name "image_id" may confuse user that we only support "image_id" when create a container. This patch rename the "image_id" field to "image" in container object. Change-Id: Ie3639feb2a2a90300662b74f186ef998d38d6cc4 Closes-Bug: #1466278 Closes-Bug: #1465558
This commit is contained in:
parent
5d94fc8a06
commit
8f1255f0f0
|
@ -356,7 +356,7 @@ Next we will create a container in this bay. This container will ping the
|
|||
address 8.8.8.8 four times. ::
|
||||
|
||||
$ BAY_UUID=$(magnum bay-list | awk '/ swarmbay /{print $2}')
|
||||
$ magnum container-create --name testcontainer --image_id cirros\
|
||||
$ magnum container-create --name testcontainer --image cirros\
|
||||
--bay $BAY_UUID\
|
||||
--command "ping -c 4 8.8.8.8"
|
||||
+------------+----------------------------------------+
|
||||
|
@ -366,7 +366,7 @@ address 8.8.8.8 four times. ::
|
|||
| links | ... |
|
||||
| bay_uuid | eda91c1e-6103-45d4-ab09-3f316310fa8e |
|
||||
| updated_at | None |
|
||||
| image_id | cirros |
|
||||
| image | cirros |
|
||||
| command | ping -c 4 8.8.8.8 |
|
||||
| created_at | 2015-04-22T20:21:11+00:00 |
|
||||
| name | test-container |
|
||||
|
|
|
@ -72,8 +72,8 @@ class Container(base.APIBase):
|
|||
name = wtypes.StringType(min_length=1, max_length=255)
|
||||
"""Name of this container"""
|
||||
|
||||
image_id = wtypes.text
|
||||
"""The image name or UUID to use as a base image for this baymodel"""
|
||||
image = wtypes.text
|
||||
"""The image name or ID to use as a base image for this container"""
|
||||
|
||||
bay_uuid = wsme.wsproperty(types.uuid, _get_bay_uuid, _set_bay_uuid,
|
||||
mandatory=True)
|
||||
|
@ -101,7 +101,7 @@ class Container(base.APIBase):
|
|||
def _convert_with_links(container, url, expand=True):
|
||||
if not expand:
|
||||
container.unset_fields_except(['uuid', 'name', 'bay_uuid',
|
||||
'image_id', 'command', 'status'])
|
||||
'image', 'command', 'status'])
|
||||
|
||||
container.links = [link.Link.make_link(
|
||||
'self', url,
|
||||
|
@ -122,7 +122,7 @@ class Container(base.APIBase):
|
|||
def sample(cls, expand=True):
|
||||
sample = cls(uuid='27e3153e-d5bf-4b7e-b517-fb518e17f34c',
|
||||
name='example',
|
||||
image_id='ubuntu',
|
||||
image='ubuntu',
|
||||
command='env',
|
||||
status='Running',
|
||||
bay_uuid="fff114da-3bfa-4a0f-a123-c0dffad9718e",
|
||||
|
|
|
@ -15,8 +15,8 @@ import docker
|
|||
from docker.utils import utils
|
||||
|
||||
|
||||
def parse_docker_image(image_id):
|
||||
image_parts = image_id.split(':', 1)
|
||||
def parse_docker_image(image):
|
||||
image_parts = image.split(':', 1)
|
||||
|
||||
image_repo = image_parts[0]
|
||||
image_tag = None
|
||||
|
|
|
@ -114,14 +114,14 @@ class Handler(object):
|
|||
@wrap_container_exception
|
||||
def container_create(self, context, name, container_uuid, container):
|
||||
docker = self.get_docker_client(context, container)
|
||||
image_id = container.image_id
|
||||
image = container.image
|
||||
LOG.debug('Creating container with image %s name %s'
|
||||
% (image_id, name))
|
||||
% (image, name))
|
||||
try:
|
||||
image_repo, image_tag = docker_utils.parse_docker_image(image_id)
|
||||
image_repo, image_tag = docker_utils.parse_docker_image(image)
|
||||
docker.pull(image_repo, tag=image_tag)
|
||||
docker.inspect_image(self._encode_utf8(container.image_id))
|
||||
docker.create_container(image_id, name=name,
|
||||
docker.inspect_image(self._encode_utf8(container.image))
|
||||
docker.create_container(image, name=name,
|
||||
hostname=container_uuid,
|
||||
command=container.command)
|
||||
container.status = obj_container.STOPPED
|
||||
|
|
|
@ -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.
|
||||
"""rename_container_image_id
|
||||
|
||||
Revision ID: 1c1ff5e56048
|
||||
Revises: 156ceb17fb0a
|
||||
Create Date: 2015-06-18 10:21:40.991734
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '1c1ff5e56048'
|
||||
down_revision = '156ceb17fb0a'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.alter_column('container', 'image_id',
|
||||
new_column_name='image',
|
||||
existing_type=sa.String(255))
|
|
@ -408,8 +408,8 @@ class Connection(api.Connection):
|
|||
|
||||
if 'name' in filters:
|
||||
query = query.filter_by(name=filters['name'])
|
||||
if 'image_id' in filters:
|
||||
query = query.filter_by(image_id=filters['image_id'])
|
||||
if 'image' in filters:
|
||||
query = query.filter_by(image=filters['image'])
|
||||
if 'project_id' in filters:
|
||||
query = query.filter_by(project_id=filters['project_id'])
|
||||
if 'user_id' in filters:
|
||||
|
|
|
@ -186,7 +186,7 @@ class Container(Base):
|
|||
user_id = Column(String(255))
|
||||
uuid = Column(String(36))
|
||||
name = Column(String(255))
|
||||
image_id = Column(String(255))
|
||||
image = Column(String(255))
|
||||
command = Column(String(255))
|
||||
bay_uuid = Column(String(36))
|
||||
status = Column(String(20))
|
||||
|
|
|
@ -40,7 +40,7 @@ class Container(base.MagnumPersistentObject, base.MagnumObject,
|
|||
'name': fields.StringField(nullable=True),
|
||||
'project_id': fields.StringField(nullable=True),
|
||||
'user_id': fields.StringField(nullable=True),
|
||||
'image_id': fields.StringField(nullable=True),
|
||||
'image': fields.StringField(nullable=True),
|
||||
'command': fields.StringField(nullable=True),
|
||||
'bay_uuid': fields.StringField(nullable=True),
|
||||
'status': fields.StringField(nullable=True),
|
||||
|
|
|
@ -35,7 +35,7 @@ class TestContainerController(db_base.DbTestCase):
|
|||
def test_create_container(self, mock_container_create,):
|
||||
mock_container_create.side_effect = lambda x, y, z: z
|
||||
|
||||
params = ('{"name": "My Docker", "image_id": "ubuntu",'
|
||||
params = ('{"name": "My Docker", "image": "ubuntu",'
|
||||
'"command": "env",'
|
||||
'"bay_uuid": "fff114da-3bfa-4a0f-a123-c0dffad9718e"}')
|
||||
response = self.app.post('/v1/containers',
|
||||
|
@ -54,7 +54,7 @@ class TestContainerController(db_base.DbTestCase):
|
|||
mock_container_show):
|
||||
mock_container_create.side_effect = lambda x, y, z: z
|
||||
# Create a container with a command
|
||||
params = ('{"name": "My Docker", "image_id": "ubuntu",'
|
||||
params = ('{"name": "My Docker", "image": "ubuntu",'
|
||||
'"command": "env",'
|
||||
'"bay_uuid": "fff114da-3bfa-4a0f-a123-c0dffad9718e"}')
|
||||
response = self.app.post('/v1/containers',
|
||||
|
@ -92,7 +92,7 @@ class TestContainerController(db_base.DbTestCase):
|
|||
mock_container_show):
|
||||
mock_container_create.side_effect = lambda x, y, z: z
|
||||
# Create a container with a command
|
||||
params = ('{"name": "My Docker", "image_id": "ubuntu",'
|
||||
params = ('{"name": "My Docker", "image": "ubuntu",'
|
||||
'"command": "env",'
|
||||
'"bay_uuid": "fff114da-3bfa-4a0f-a123-c0dffad9718e"}')
|
||||
response = self.app.post('/v1/containers',
|
||||
|
@ -124,7 +124,7 @@ class TestContainerController(db_base.DbTestCase):
|
|||
@patch('magnum.conductor.api.API.container_create')
|
||||
def test_create_container_without_name(self, mock_container_create):
|
||||
# No name param
|
||||
params = ('{"image_id": "ubuntu", "command": "env",'
|
||||
params = ('{"image": "ubuntu", "command": "env",'
|
||||
'"bay_uuid": "fff114da-3bfa-4a0f-a123-c0dffad9718e"}')
|
||||
self.assertRaises(AppError, self.app.post, '/v1/containers',
|
||||
params=params, content_type='application/json')
|
||||
|
@ -133,7 +133,7 @@ class TestContainerController(db_base.DbTestCase):
|
|||
@patch('magnum.conductor.api.API.container_create')
|
||||
def test_create_container_invalid_long_name(self, mock_container_create,):
|
||||
# Long name
|
||||
params = ('{"name": "' + 'i' * 256 + '", "image_id": "ubuntu",'
|
||||
params = ('{"name": "' + 'i' * 256 + '", "image": "ubuntu",'
|
||||
'"command": "env",'
|
||||
'"bay_uuid": "fff114da-3bfa-4a0f-a123-c0dffad9718e"}')
|
||||
self.assertRaises(AppError, self.app.post, '/v1/containers',
|
||||
|
|
|
@ -111,19 +111,19 @@ class TestDockerConductor(base.BaseTestCase):
|
|||
mock_get_docker_client.return_value = mock_docker
|
||||
|
||||
mock_container = mock.MagicMock()
|
||||
mock_container.image_id = 'test_image:some_tag'
|
||||
mock_container.image = 'test_image:some_tag'
|
||||
mock_container.command = None
|
||||
|
||||
container = self.conductor.container_create(
|
||||
None, 'some-name',
|
||||
'some-uuid', mock_container)
|
||||
|
||||
utf8_image_id = self.conductor._encode_utf8(mock_container.image_id)
|
||||
utf8_image = self.conductor._encode_utf8(mock_container.image)
|
||||
mock_docker.pull.assert_called_once_with('test_image',
|
||||
tag='some_tag')
|
||||
mock_docker.inspect_image.assert_called_once_with(utf8_image_id)
|
||||
mock_docker.inspect_image.assert_called_once_with(utf8_image)
|
||||
mock_docker.create_container.assert_called_once_with(
|
||||
mock_container.image_id,
|
||||
mock_container.image,
|
||||
name='some-name',
|
||||
hostname='some-uuid',
|
||||
command=None)
|
||||
|
@ -135,19 +135,19 @@ class TestDockerConductor(base.BaseTestCase):
|
|||
mock_get_docker_client.return_value = mock_docker
|
||||
|
||||
mock_container = mock.MagicMock()
|
||||
mock_container.image_id = 'test_image:some_tag'
|
||||
mock_container.image = 'test_image:some_tag'
|
||||
mock_container.command = 'env'
|
||||
|
||||
container = self.conductor.container_create(
|
||||
None, 'some-name',
|
||||
'some-uuid', mock_container)
|
||||
|
||||
utf8_image_id = self.conductor._encode_utf8(mock_container.image_id)
|
||||
utf8_image = self.conductor._encode_utf8(mock_container.image)
|
||||
mock_docker.pull.assert_called_once_with('test_image',
|
||||
tag='some_tag')
|
||||
mock_docker.inspect_image.assert_called_once_with(utf8_image_id)
|
||||
mock_docker.inspect_image.assert_called_once_with(utf8_image)
|
||||
mock_docker.create_container.assert_called_once_with(
|
||||
mock_container.image_id,
|
||||
mock_container.image,
|
||||
name='some-name',
|
||||
hostname='some-uuid',
|
||||
command='env')
|
||||
|
@ -158,7 +158,7 @@ class TestDockerConductor(base.BaseTestCase):
|
|||
mock_docker = mock.MagicMock()
|
||||
mock_get_docker_client.return_value = mock_docker
|
||||
mock_container = mock.MagicMock()
|
||||
mock_container.image_id = 'test_image:some_tag'
|
||||
mock_container.image = 'test_image:some_tag'
|
||||
with patch.object(errors.APIError, '__str__',
|
||||
return_value='hit error') as mock_init:
|
||||
mock_docker.pull = mock.Mock(
|
||||
|
|
|
@ -112,20 +112,20 @@ class DbContainerTestCase(base.DbTestCase):
|
|||
|
||||
def test_update_container(self):
|
||||
container = utils.create_test_container()
|
||||
old_image = container.image_id
|
||||
old_image = container.image
|
||||
new_image = 'new-image'
|
||||
self.assertNotEqual(old_image, new_image)
|
||||
|
||||
res = self.dbapi.update_container(container.id,
|
||||
{'image_id': new_image})
|
||||
self.assertEqual(new_image, res.image_id)
|
||||
{'image': new_image})
|
||||
self.assertEqual(new_image, res.image)
|
||||
|
||||
def test_update_container_not_found(self):
|
||||
container_uuid = magnum_utils.generate_uuid()
|
||||
new_image = 'new-image'
|
||||
self.assertRaises(exception.ContainerNotFound,
|
||||
self.dbapi.update_container,
|
||||
container_uuid, {'image_id': new_image})
|
||||
container_uuid, {'image': new_image})
|
||||
|
||||
def test_update_container_uuid(self):
|
||||
container = utils.create_test_container()
|
||||
|
|
|
@ -182,7 +182,7 @@ def get_test_container(**kw):
|
|||
'name': kw.get('name', 'container1'),
|
||||
'project_id': kw.get('project_id', 'fake_project'),
|
||||
'user_id': kw.get('user_id', 'fake_user'),
|
||||
'image_id': kw.get('image_id', 'ubuntu'),
|
||||
'image': kw.get('image', 'ubuntu'),
|
||||
'created_at': kw.get('created_at'),
|
||||
'updated_at': kw.get('updated_at'),
|
||||
'command': kw.get('command', 'fake_command'),
|
||||
|
|
|
@ -97,12 +97,12 @@ class TestContainerObject(base.DbTestCase):
|
|||
with mock.patch.object(self.dbapi, 'update_container',
|
||||
autospec=True) as mock_update_container:
|
||||
container = objects.Container.get_by_uuid(self.context, uuid)
|
||||
container.image_id = 'container.img'
|
||||
container.image = 'container.img'
|
||||
container.save()
|
||||
|
||||
mock_get_container.assert_called_once_with(self.context, uuid)
|
||||
mock_update_container.assert_called_once_with(
|
||||
uuid, {'image_id': 'container.img'})
|
||||
uuid, {'image': 'container.img'})
|
||||
self.assertEqual(self.context, container._context)
|
||||
|
||||
def test_refresh(self):
|
||||
|
|
Loading…
Reference in New Issue