Merge "Validate flavor image min ram when resize volume-backed instance"
This commit is contained in:
commit
3abea334d5
@ -4269,6 +4269,12 @@ class API:
|
|||||||
if volume_backed:
|
if volume_backed:
|
||||||
self._validate_flavor_image_numa_pci(
|
self._validate_flavor_image_numa_pci(
|
||||||
image, new_flavor, validate_pci=True)
|
image, new_flavor, validate_pci=True)
|
||||||
|
# The server that image-backed already has the verification of
|
||||||
|
# image min_ram when calling _validate_flavor_image_nostatus.
|
||||||
|
# Here, the verification is added for the server that
|
||||||
|
# volume-backed.
|
||||||
|
if new_flavor['memory_mb'] < int(image.get('min_ram', 0)):
|
||||||
|
raise exception.FlavorMemoryTooSmall()
|
||||||
else:
|
else:
|
||||||
self._validate_flavor_image_nostatus(
|
self._validate_flavor_image_nostatus(
|
||||||
context, image, new_flavor, root_bdm=None,
|
context, image, new_flavor, root_bdm=None,
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
import fixtures
|
import fixtures
|
||||||
|
|
||||||
from nova.tests.fixtures import libvirt as fakelibvirt
|
from nova.tests.fixtures import libvirt as fakelibvirt
|
||||||
|
from nova.tests.functional.api import client
|
||||||
from nova.tests.functional.libvirt import base
|
from nova.tests.functional.libvirt import base
|
||||||
|
|
||||||
|
|
||||||
@ -56,5 +57,11 @@ class Bug2007968RegressionTest(base.ServersTestBase):
|
|||||||
# This can cause the instance for boot from volume to be allowed to
|
# This can cause the instance for boot from volume to be allowed to
|
||||||
# get to the resize verify status, but the instance's application runs
|
# get to the resize verify status, but the instance's application runs
|
||||||
# abnormally due to insufficient memory, and it may be killed by OOM.
|
# abnormally due to insufficient memory, and it may be killed by OOM.
|
||||||
server = self._resize_server(server, new_flavor)
|
|
||||||
self.assertEqual(server['status'], 'VERIFY_RESIZE')
|
# After the fix, compute api will directly raise FlavorMemoryTooSmall
|
||||||
|
# and will not continue the resize.
|
||||||
|
ex = self.assertRaises(client.OpenStackApiException,
|
||||||
|
self._resize_server, server, new_flavor)
|
||||||
|
self.assertEqual(400, ex.response.status_code)
|
||||||
|
self.assertIn('Flavor\'s memory is too small for requested image.',
|
||||||
|
ex.response.text)
|
||||||
|
@ -2376,6 +2376,39 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||||||
mock_resize.assert_not_called()
|
mock_resize.assert_not_called()
|
||||||
mock_save.assert_not_called()
|
mock_save.assert_not_called()
|
||||||
|
|
||||||
|
@mock.patch('nova.compute.utils.is_volume_backed_instance',
|
||||||
|
return_value=True)
|
||||||
|
@mock.patch('nova.servicegroup.api.API.service_is_up',
|
||||||
|
new=mock.Mock(return_value=True))
|
||||||
|
@mock.patch.object(objects.Instance, 'save')
|
||||||
|
@mock.patch.object(compute_api.API, '_record_action_start')
|
||||||
|
@mock.patch.object(quotas_obj.Quotas, 'limit_check_project_and_user')
|
||||||
|
@mock.patch.object(quotas_obj.Quotas, 'count_as_dict')
|
||||||
|
@mock.patch.object(flavors, 'get_flavor_by_flavor_id')
|
||||||
|
def test_resize_vol_backed_smaller_min_ram(self, mock_get_flavor,
|
||||||
|
mock_count, mock_limit,
|
||||||
|
mock_record, mock_save,
|
||||||
|
mock_is_vol_backed):
|
||||||
|
mock_resize = self.useFixture(fixtures.MockPatchObject(
|
||||||
|
self.compute_api.compute_task_api, 'resize_instance')).mock
|
||||||
|
# Resize down from 512 MB to 64 MB.
|
||||||
|
params = dict(image_ref='', system_metadata={'min_ram': 512})
|
||||||
|
fake_inst = self._create_instance_obj(params=params)
|
||||||
|
new_flavor = self._create_flavor(id=200, flavorid=200,
|
||||||
|
name='new_flavor', disabled=False,
|
||||||
|
memory_mb=64)
|
||||||
|
mock_get_flavor.return_value = new_flavor
|
||||||
|
self.assertRaises(exception.FlavorMemoryTooSmall,
|
||||||
|
self.compute_api.resize, self.context,
|
||||||
|
fake_inst, flavor_id=new_flavor.id)
|
||||||
|
mock_get_flavor.assert_called_once_with(200, read_deleted='no')
|
||||||
|
# Should never reach these.
|
||||||
|
mock_count.assert_not_called()
|
||||||
|
mock_limit.assert_not_called()
|
||||||
|
mock_record.assert_not_called()
|
||||||
|
mock_resize.assert_not_called()
|
||||||
|
mock_save.assert_not_called()
|
||||||
|
|
||||||
@mock.patch('nova.servicegroup.api.API.service_is_up',
|
@mock.patch('nova.servicegroup.api.API.service_is_up',
|
||||||
new=mock.Mock(return_value=True))
|
new=mock.Mock(return_value=True))
|
||||||
@mock.patch.object(objects.Instance, 'save')
|
@mock.patch.object(objects.Instance, 'save')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user