Introduce container resize API

Currently, the container resize is
implemented at the PATCH /containers/<container>
This PS seperating container resize (i.e
update cpu/memory of container) from PATCH api

Closes-Bug: #1759458

Change-Id: Ibcf9913b0dd31013abadf1f9eb70c761870a2c84
This commit is contained in:
rajat29 2018-06-08 15:29:28 +05:30 committed by Hongbin Lu
parent fb0dcf1a18
commit fda6fa43f9
11 changed files with 89 additions and 13 deletions

View File

@ -168,6 +168,7 @@ class ContainersController(base.Controller):
'rename': ['POST'],
'attach': ['GET'],
'resize': ['POST'],
'resize_container': ['POST'],
'top': ['GET'],
'get_archive': ['GET'],
'put_archive': ['POST'],
@ -597,6 +598,31 @@ class ContainersController(base.Controller):
return view.format_container(context, pecan.request.host_url,
container)
@base.Controller.api_version("1.19")
@pecan.expose('json')
@exception.wrap_pecan_controller_exception
@validation.validated(schema.container_update)
def resize_container(self, container_ident, **kwargs):
"""Resize an existing container.
:param container_ident: UUID or name of a container.
:param kwargs: cpu/memory to be updated.
"""
container = utils.get_container(container_ident)
check_policy_on_container(container.as_dict(),
"container:resize_container")
utils.validate_container_state(container, 'resize_container')
if 'memory' in kwargs:
kwargs['memory'] = str(kwargs['memory'])
if 'cpu' in kwargs:
kwargs['cpu'] = float(kwargs['cpu'])
context = pecan.request.context
compute_api = pecan.request.compute_api
compute_api.resize_container(context, container, kwargs)
pecan.response.status = 202
return view.format_container(context, pecan.request.host_url,
container)
@pecan.expose('json')
@exception.wrap_pecan_controller_exception
@validation.validate_query_param(pecan.request, schema.query_param_delete)

View File

@ -51,10 +51,11 @@ REST_API_VERSION_HISTORY = """REST API Version History:
* 1.16 - Modify restart_policy to capsule spec content
* 1.17 - Add support for detaching ports
* 1.18 - Modify the response of network list
* 1.19 - Intoduce container resize API
"""
BASE_VER = '1.1'
CURRENT_MAX_VER = '1.18'
CURRENT_MAX_VER = '1.19'
class Version(object):

View File

@ -161,3 +161,9 @@ user documentation.
}
]
}
1.19
----
Introduce an API endpoint for resizing a container, such as changing the
CPU or memory of the container.

View File

@ -418,6 +418,17 @@ rules = [
}
]
),
policy.DocumentedRuleDefault(
name=CONTAINER % 'resize_container',
check_str=base.RULE_ADMIN_OR_OWNER,
description='Resize an existing container.',
operations=[
{
'path': '/v1/containers/{container_ident}/resize_container',
'method': 'POST'
}
]
),
]

View File

@ -80,7 +80,9 @@ VALID_STATES = {
'add_security_group': [consts.CREATED, consts.RUNNING, consts.STOPPED,
consts.PAUSED],
'remove_security_group': [consts.CREATED, consts.RUNNING, consts.STOPPED,
consts.PAUSED]
consts.PAUSED],
'resize_container': [consts.CREATED, consts.RUNNING, consts.STOPPED,
consts.PAUSED]
}
VALID_CONTAINER_FILED = {

View File

@ -236,3 +236,6 @@ class API(object):
def network_create(self, context, network):
return self.rpcapi.network_create(context, network)
def resize_container(self, context, container, *args):
return self.rpcapi.resize_container(context, container, *args)

View File

@ -1217,3 +1217,10 @@ class Manager(periodic_task.PeriodicTasks):
docker_network = self.driver.create_network(context, network)
network.network_id = docker_network['Id']
network.save()
def resize_container(self, context, container, patch):
@utils.synchronized(container.uuid)
def do_container_resize():
self.container_update(context, container, patch)
utils.spawn_n(do_container_resize)

View File

@ -123,6 +123,10 @@ class API(rpc_service.API):
return self._call(container.host, 'container_update',
container=container, patch=patch)
def resize_container(self, context, container, patch):
self._cast(container.host, 'resize_container',
container=container, patch=patch)
@check_container_host
def container_attach(self, context, container):
return self._call(container.host, 'container_attach',

View File

@ -26,7 +26,7 @@ from zun.tests.unit.db import base
PATH_PREFIX = '/v1'
CURRENT_VERSION = "container 1.18"
CURRENT_VERSION = "container 1.19"
class FunctionalTest(base.DbTestCase):

View File

@ -28,7 +28,7 @@ class TestRootController(api_base.FunctionalTest):
'default_version':
{'id': 'v1',
'links': [{'href': 'http://localhost/v1/', 'rel': 'self'}],
'max_version': '1.18',
'max_version': '1.19',
'min_version': '1.1',
'status': 'CURRENT'},
'description': 'Zun is an OpenStack project which '
@ -37,7 +37,7 @@ class TestRootController(api_base.FunctionalTest):
'versions': [{'id': 'v1',
'links': [{'href': 'http://localhost/v1/',
'rel': 'self'}],
'max_version': '1.18',
'max_version': '1.19',
'min_version': '1.1',
'status': 'CURRENT'}]}

View File

@ -1524,10 +1524,8 @@ class TestContainerController(api_base.FunctionalTest):
@patch('zun.common.utils.validate_container_state')
@patch('zun.compute.api.API.container_resize')
@patch('zun.objects.Container.get_by_name')
def test_resize_container_by_uuid(self,
mock_get_by_uuid,
mock_container_resize,
mock_validate):
def test_resize_by_uuid(self, mock_get_by_uuid, mock_container_resize,
mock_validate):
test_container_obj = objects.Container(self.context,
**utils.get_test_container())
mock_container_resize.return_value = test_container_obj
@ -1546,10 +1544,8 @@ class TestContainerController(api_base.FunctionalTest):
@patch('zun.common.utils.validate_container_state')
@patch('zun.compute.api.API.container_resize')
@patch('zun.objects.Container.get_by_uuid')
def test_resize_container_with_exception(self,
mock_get_by_uuid,
mock_container_resize,
mock_validate):
def test_resize_with_exception(self, mock_get_by_uuid,
mock_container_resize, mock_validate):
mock_container_resize.return_value = ""
test_container = utils.get_test_container()
test_container_obj = objects.Container(self.context, **test_container)
@ -1563,6 +1559,26 @@ class TestContainerController(api_base.FunctionalTest):
(container_uuid, 'resize'), body)
self.assertTrue(mock_container_resize.called)
@patch('zun.common.utils.validate_container_state')
@patch('zun.compute.api.API.resize_container')
@patch('zun.objects.Container.get_by_name')
def test_resize_container(self, mock_get_by_uuid,
mock_resize_container, mock_validate):
test_container_obj = objects.Container(self.context,
**utils.get_test_container())
mock_resize_container.return_value = test_container_obj
test_container = utils.get_test_container()
test_container_obj = objects.Container(self.context, **test_container)
mock_get_by_uuid.return_value = test_container_obj
container_name = test_container.get('name')
url = '/v1/containers/%s/resize_container/' % container_name
params = {'cpu': 1, 'memory': '512'}
response = self.post(url, params)
self.assertEqual(202, response.status_int)
mock_resize_container.assert_called_once_with(
mock.ANY, test_container_obj, params)
@patch('zun.common.utils.validate_container_state')
@patch('zun.compute.api.API.container_top')
@patch('zun.objects.Container.get_by_uuid')