From c7de85445ad2c153710e066df7eba23d68d32010 Mon Sep 17 00:00:00 2001 From: jichenjc Date: Fri, 14 Aug 2015 02:42:58 +0800 Subject: [PATCH] Prevent boot if ephemeral disk size > flavor value Nova allows following command nova boot --image 3ec2603b-9113-4ca1-92cf-690e573985bd --flavor 11 --block-device source=blank,dest=local --block-device source=blank,dest=local test which in turn translate the ephemeral disk mappings into 2 default ephemeral disk and makes the total spanwed ephemeral disk size greater than flavor ephemeral disk. This patch add checks to this kind of situation and prevents it. Change-Id: I1952eeb04bf3835182e575e418632a6d611c84e9 Closes-Bug: 1483645 --- nova/compute/api.py | 2 +- nova/exception.py | 4 ++- nova/tests/unit/compute/test_compute.py | 34 +++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/nova/compute/api.py b/nova/compute/api.py index 17490a1f4ce7..ba8b7127c4ad 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -1309,7 +1309,7 @@ class API(base.Base): "(source: 'blank', dest: 'volume') need to have non-zero " "size")) - ephemeral_size = sum(bdm.volume_size or 0 + ephemeral_size = sum(bdm.volume_size or instance_type['ephemeral_gb'] for bdm in block_device_mappings if block_device.new_format_is_ephemeral(bdm)) if ephemeral_size > instance_type['ephemeral_gb']: diff --git a/nova/exception.py b/nova/exception.py index 63d80a9c07b9..116dd0885149 100644 --- a/nova/exception.py +++ b/nova/exception.py @@ -263,7 +263,9 @@ class InvalidBDMLocalsLimit(InvalidBDM): class InvalidBDMEphemeralSize(InvalidBDM): msg_fmt = _("Ephemeral disks requested are larger than " - "the instance type allows.") + "the instance type allows. If no size is given " + "in one block device mapping, flavor ephemeral " + "size will be used.") class InvalidBDMSwapSize(InvalidBDM): diff --git a/nova/tests/unit/compute/test_compute.py b/nova/tests/unit/compute/test_compute.py index 19428460bcd7..6b2e0a61ea72 100644 --- a/nova/tests/unit/compute/test_compute.py +++ b/nova/tests/unit/compute/test_compute.py @@ -1057,6 +1057,40 @@ class ComputeVolumeTestCase(BaseTestCase): self.context, instance, instance_type, mappings_) + def test_validate_bdm_with_more_than_one_default(self): + instance_type = {'swap': 1, 'ephemeral_gb': 1} + all_mappings = [fake_block_device.FakeDbBlockDeviceDict({ + 'id': 1, + 'no_device': None, + 'source_type': 'volume', + 'destination_type': 'volume', + 'snapshot_id': None, + 'volume_size': 1, + 'device_name': 'vda', + 'boot_index': 0, + 'delete_on_termination': False}, anon=True), + fake_block_device.FakeDbBlockDeviceDict({ + 'device_name': '/dev/vdb', + 'source_type': 'blank', + 'destination_type': 'local', + 'device_type': 'disk', + 'volume_size': None, + 'boot_index': -1}, anon=True), + fake_block_device.FakeDbBlockDeviceDict({ + 'device_name': '/dev/vdc', + 'source_type': 'blank', + 'destination_type': 'local', + 'device_type': 'disk', + 'volume_size': None, + 'boot_index': -1}, anon=True)] + all_mappings = block_device_obj.block_device_make_list_from_dicts( + self.context, all_mappings) + + self.assertRaises(exception.InvalidBDMEphemeralSize, + self.compute_api._validate_bdm, + self.context, self.instance, + instance_type, all_mappings) + def test_validate_bdm_media_service_exceptions(self): instance_type = {'swap': 1, 'ephemeral_gb': 1} bdms = [fake_block_device.FakeDbBlockDeviceDict({