VMware: add resource limits for disk
The flavor extra specs for quotas has been extended to support quota:disk_io_limit - The utilization of a virtual machine will not exceed this limit. The unit is number of I/O per second. quota:disk_io_reservation - Reservation control is used to provide guaranteed allocation in terms of IOPS quota:disk_io_shares_level - the allocation level. This can be 'custom', 'high' 'normal' or 'low'. quota:disk_io_shares_share - in the event that 'custom' is used, this is the number of shares. This enables the VMware driver to enable disk allocations for the running instance. Please see http://goo.gl/6sHwIA for a detailed explanation of the above. DocImpact The is part of the blueprint vmware-limits Change-Id: I6797ad3442895cd73f240590286b4ae13986291f
This commit is contained in:
parent
2b992673b5
commit
42524209e2
|
@ -1092,6 +1092,7 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
|
|||
mock_extend_virtual_disk,
|
||||
mock_sized_image_exists,
|
||||
flavor_fits_image=False):
|
||||
extra_specs = vm_util.ExtraSpecs()
|
||||
file_size = 10 * units.Gi if flavor_fits_image else 5 * units.Gi
|
||||
image_info = images.VMwareImage(
|
||||
image_id=self._image_id,
|
||||
|
@ -1103,7 +1104,7 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
|
|||
mock_imagecache.get_image_cache_folder.return_value = cache_root_folder
|
||||
vi = vmops.VirtualMachineInstanceConfigInfo(
|
||||
self._instance, image_info,
|
||||
self._ds, self._dc_info, mock_imagecache)
|
||||
self._ds, self._dc_info, mock_imagecache, extra_specs)
|
||||
|
||||
sized_cached_image_ds_loc = cache_root_folder.join(
|
||||
"%s.%s.vmdk" % (self._image_id, vi.root_gb))
|
||||
|
@ -1128,7 +1129,8 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
|
|||
"fake_vm_ref", self._instance, vi.ii.adapter_type,
|
||||
vi.ii.disk_type,
|
||||
str(sized_cached_image_ds_loc),
|
||||
vi.root_gb * units.Mi, False)
|
||||
vi.root_gb * units.Mi, False,
|
||||
disk_io_limits=vi._extra_specs.disk_io_limits)
|
||||
|
||||
def test_use_disk_image_as_linked_clone(self):
|
||||
self._test_use_disk_image_as_linked_clone()
|
||||
|
@ -1142,6 +1144,7 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
|
|||
mock_copy_virtual_disk,
|
||||
mock_extend_virtual_disk,
|
||||
flavor_fits_image=False):
|
||||
extra_specs = vm_util.ExtraSpecs()
|
||||
file_size = 10 * units.Gi if flavor_fits_image else 5 * units.Gi
|
||||
image_info = images.VMwareImage(
|
||||
image_id=self._image_id,
|
||||
|
@ -1153,7 +1156,8 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
|
|||
mock_imagecache.get_image_cache_folder.return_value = cache_root_folder
|
||||
vi = vmops.VirtualMachineInstanceConfigInfo(
|
||||
self._instance, image_info,
|
||||
self._ds, self._dc_info, mock_imagecache)
|
||||
self._ds, self._dc_info, mock_imagecache,
|
||||
extra_specs)
|
||||
|
||||
self._vmops._volumeops = mock.Mock()
|
||||
mock_attach_disk_to_vm = self._vmops._volumeops.attach_disk_to_vm
|
||||
|
@ -1173,7 +1177,8 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
|
|||
mock_attach_disk_to_vm.assert_called_once_with(
|
||||
"fake_vm_ref", self._instance, vi.ii.adapter_type,
|
||||
vi.ii.disk_type, '[fake_ds] fake_uuid/fake_uuid.vmdk',
|
||||
vi.root_gb * units.Mi, False)
|
||||
vi.root_gb * units.Mi, False,
|
||||
disk_io_limits=vi._extra_specs.disk_io_limits)
|
||||
|
||||
def test_use_disk_image_as_full_clone(self):
|
||||
self._test_use_disk_image_as_full_clone()
|
||||
|
@ -1187,6 +1192,7 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
|
|||
mock_create_virtual_disk,
|
||||
mock_attach_cdrom,
|
||||
with_root_disk):
|
||||
extra_specs = vm_util.ExtraSpecs()
|
||||
image_info = images.VMwareImage(
|
||||
image_id=self._image_id,
|
||||
file_size=10 * units.Mi,
|
||||
|
@ -1197,7 +1203,7 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
|
|||
mock_imagecache.get_image_cache_folder.return_value = cache_root_folder
|
||||
vi = vmops.VirtualMachineInstanceConfigInfo(
|
||||
self._instance, image_info,
|
||||
self._ds, self._dc_info, mock_imagecache)
|
||||
self._ds, self._dc_info, mock_imagecache, extra_specs)
|
||||
|
||||
self._vmops._volumeops = mock.Mock()
|
||||
mock_attach_disk_to_vm = self._vmops._volumeops.attach_disk_to_vm
|
||||
|
@ -1219,7 +1225,8 @@ class VMwareVMOpsTestCase(test.NoDBTestCase):
|
|||
"fake_vm_ref", self._instance,
|
||||
vi.ii.adapter_type, vi.ii.disk_type,
|
||||
'[fake_ds] fake_uuid/fake_uuid.vmdk',
|
||||
vi.root_gb * units.Mi, linked_clone)
|
||||
vi.root_gb * units.Mi, linked_clone,
|
||||
disk_io_limits=vi._extra_specs.disk_io_limits)
|
||||
|
||||
def test_use_iso_image_with_root_disk(self):
|
||||
self._test_use_iso_image(with_root_disk=True)
|
||||
|
|
|
@ -96,7 +96,7 @@ class ExtraSpecs(object):
|
|||
|
||||
def __init__(self, cpu_limits=None, hw_version=None,
|
||||
storage_policy=None, cores_per_socket=None,
|
||||
memory_limits=None):
|
||||
memory_limits=None, disk_io_limits=None):
|
||||
"""ExtraSpecs object holds extra_specs for the instance."""
|
||||
if cpu_limits is None:
|
||||
cpu_limits = Limits()
|
||||
|
@ -104,6 +104,9 @@ class ExtraSpecs(object):
|
|||
if memory_limits is None:
|
||||
memory_limits = Limits()
|
||||
self.memory_limits = memory_limits
|
||||
if disk_io_limits is None:
|
||||
disk_io_limits = Limits()
|
||||
self.disk_io_limits = disk_io_limits
|
||||
self.hw_version = hw_version
|
||||
self.storage_policy = storage_policy
|
||||
self.cores_per_socket = cores_per_socket
|
||||
|
@ -473,7 +476,8 @@ def get_vmdk_attach_config_spec(client_factory,
|
|||
linked_clone=False,
|
||||
controller_key=None,
|
||||
unit_number=None,
|
||||
device_name=None):
|
||||
device_name=None,
|
||||
disk_io_limits=None):
|
||||
"""Builds the vmdk attach config spec."""
|
||||
config_spec = client_factory.create('ns0:VirtualMachineConfigSpec')
|
||||
|
||||
|
@ -481,7 +485,7 @@ def get_vmdk_attach_config_spec(client_factory,
|
|||
virtual_device_config_spec = create_virtual_disk_spec(client_factory,
|
||||
controller_key, disk_type, file_path,
|
||||
disk_size, linked_clone,
|
||||
unit_number, device_name)
|
||||
unit_number, device_name, disk_io_limits)
|
||||
|
||||
device_config_spec.append(virtual_device_config_spec)
|
||||
|
||||
|
@ -766,7 +770,8 @@ def create_virtual_disk_spec(client_factory, controller_key,
|
|||
disk_size=None,
|
||||
linked_clone=False,
|
||||
unit_number=None,
|
||||
device_name=None):
|
||||
device_name=None,
|
||||
disk_io_limits=None):
|
||||
"""Builds spec for the creation of a new/ attaching of an already existing
|
||||
Virtual Disk to the VM.
|
||||
"""
|
||||
|
@ -817,6 +822,11 @@ def create_virtual_disk_spec(client_factory, controller_key,
|
|||
virtual_disk.unitNumber = unit_number or 0
|
||||
virtual_disk.capacityInKB = disk_size or 0
|
||||
|
||||
if disk_io_limits and disk_io_limits.has_limits():
|
||||
virtual_disk.storageIOAllocation = _get_allocation_info(
|
||||
client_factory, disk_io_limits,
|
||||
'ns0:StorageIOAllocationInfo')
|
||||
|
||||
virtual_device_config.device = virtual_disk
|
||||
|
||||
return virtual_device_config
|
||||
|
|
|
@ -307,7 +307,7 @@ class VMwareVMOps(object):
|
|||
def _get_extra_specs(self, flavor, image_meta=None):
|
||||
image_meta = image_meta or objects.ImageMeta.from_dict({})
|
||||
extra_specs = vm_util.ExtraSpecs()
|
||||
for resource in ['cpu', 'memory']:
|
||||
for resource in ['cpu', 'memory', 'disk_io']:
|
||||
for (key, type) in (('limit', int),
|
||||
('reservation', int),
|
||||
('shares_level', str),
|
||||
|
@ -318,6 +318,7 @@ class VMwareVMOps(object):
|
|||
key, type(value))
|
||||
extra_specs.cpu_limits.validate()
|
||||
extra_specs.memory_limits.validate()
|
||||
extra_specs.disk_io_limits.validate()
|
||||
hw_version = flavor.extra_specs.get('vmware:hw_version')
|
||||
extra_specs.hw_version = hw_version
|
||||
if CONF.vmware.pbm_enabled:
|
||||
|
@ -1688,7 +1689,8 @@ class VMwareVMOps(object):
|
|||
vm_ref, vi.instance,
|
||||
vi.ii.adapter_type, vi.ii.disk_type,
|
||||
str(root_disk_ds_loc),
|
||||
vi.root_gb * units.Mi, False)
|
||||
vi.root_gb * units.Mi, False,
|
||||
disk_io_limits=vi._extra_specs.disk_io_limits)
|
||||
|
||||
def _sized_image_exists(self, sized_disk_ds_loc, ds_ref):
|
||||
ds_browser = self._get_ds_browser(ds_ref)
|
||||
|
@ -1761,7 +1763,8 @@ class VMwareVMOps(object):
|
|||
vm_ref, vi.instance,
|
||||
vi.ii.adapter_type, vi.ii.disk_type,
|
||||
str(sized_disk_ds_loc),
|
||||
vi.root_gb * units.Mi, vi.ii.linked_clone)
|
||||
vi.root_gb * units.Mi, vi.ii.linked_clone,
|
||||
disk_io_limits=vi._extra_specs.disk_io_limits)
|
||||
|
||||
def _use_iso_image(self, vm_ref, vi):
|
||||
"""Uses cached image as a bootable virtual cdrom."""
|
||||
|
@ -1791,7 +1794,8 @@ class VMwareVMOps(object):
|
|||
vm_ref, vi.instance,
|
||||
vi.ii.adapter_type, vi.ii.disk_type,
|
||||
str(root_disk_ds_loc),
|
||||
vi.root_gb * units.Mi, linked_clone)
|
||||
vi.root_gb * units.Mi, linked_clone,
|
||||
disk_io_limits=vi._extra_specs.disk_io_limits)
|
||||
|
||||
def _update_datacenter_cache_from_objects(self, dcs):
|
||||
"""Updates the datastore/datacenter cache."""
|
||||
|
|
|
@ -42,7 +42,7 @@ class VMwareVolumeOps(object):
|
|||
def attach_disk_to_vm(self, vm_ref, instance,
|
||||
adapter_type, disk_type, vmdk_path=None,
|
||||
disk_size=None, linked_clone=False,
|
||||
device_name=None):
|
||||
device_name=None, disk_io_limits=None):
|
||||
"""Attach disk to VM by reconfiguration."""
|
||||
instance_name = instance.name
|
||||
client_factory = self._session.vim.client.factory
|
||||
|
@ -58,7 +58,7 @@ class VMwareVolumeOps(object):
|
|||
vmdk_attach_config_spec = vm_util.get_vmdk_attach_config_spec(
|
||||
client_factory, disk_type, vmdk_path,
|
||||
disk_size, linked_clone, controller_key,
|
||||
unit_number, device_name)
|
||||
unit_number, device_name, disk_io_limits)
|
||||
if controller_spec:
|
||||
vmdk_attach_config_spec.deviceChange.append(controller_spec)
|
||||
|
||||
|
|
Loading…
Reference in New Issue