Support resource_properties key in instance reservation
This patch adds a 'resource_properties' key for instance reservation as a required parameter. If a user specifies the key when they create instance reservations, Blazar picks up hypervisors that match the key for the reservation. Partially Implements: blueprint flavors-extra-specs Change-Id: Ia8877c667116739d75381776555f91e529c1c21d
This commit is contained in:
parent
0596122a78
commit
c175f2b42c
@ -92,6 +92,7 @@ are in the ``reservation`` object.
|
||||
- reservation.memory_mb: reservation_memory_mb
|
||||
- reservation.disk_gb: reservation_disk_gb
|
||||
- reservation.affinity : reservation_affinity
|
||||
- reservation.resource_properties: reservation_resource_properties
|
||||
- reservation.flavor_id: reservation_flavor_id
|
||||
- reservation.server_group_id: reservation_server_group_id
|
||||
- reservation.aggregate_id: reservation_aggregate_id
|
||||
@ -158,6 +159,7 @@ are in the ``reservation`` object.
|
||||
- reservation.memory_mb: reservation_memory_mb
|
||||
- reservation.disk_gb: reservation_disk_gb
|
||||
- reservation.affinity : reservation_affinity
|
||||
- reservation.resource_properties: reservation_resource_properties
|
||||
|
||||
**Example of Create Lease Request**
|
||||
|
||||
@ -230,6 +232,7 @@ are in the ``reservation`` object.
|
||||
- reservation.memory_mb: reservation_memory_mb
|
||||
- reservation.disk_gb: reservation_disk_gb
|
||||
- reservation.affinity : reservation_affinity
|
||||
- reservation.resource_properties: reservation_resource_properties
|
||||
- reservation.flavor_id: reservation_flavor_id
|
||||
- reservation.server_group_id: reservation_server_group_id
|
||||
- reservation.aggregate_id: reservation_aggregate_id
|
||||
@ -330,6 +333,7 @@ are in the ``reservation`` object.
|
||||
- reservation.memory_mb: reservation_memory_mb
|
||||
- reservation.disk_gb: reservation_disk_gb
|
||||
- reservation.affinity : reservation_affinity
|
||||
- reservation.resource_properties: reservation_resource_properties
|
||||
- reservation.flavor_id: reservation_flavor_id
|
||||
- reservation.server_group_id: reservation_server_group_id
|
||||
- reservation.aggregate_id: reservation_aggregate_id
|
||||
@ -400,6 +404,7 @@ are in the ``reservation`` object.
|
||||
- reservation.memory_mb: reservation_memory_mb_optional
|
||||
- reservation.disk_gb: reservation_disk_gb_optional
|
||||
- reservation.affinity : reservation_affinity_optional
|
||||
- reservation.resource_properties: reservation_resource_properties_optional
|
||||
|
||||
**Example of Update Lease Request**
|
||||
|
||||
@ -472,6 +477,7 @@ are in the ``reservation`` object.
|
||||
- reservation.memory_mb: reservation_memory_mb
|
||||
- reservation.disk_gb: reservation_disk_gb
|
||||
- reservation.affinity : reservation_affinity
|
||||
- reservation.resource_properties: reservation_resource_properties
|
||||
- reservation.flavor_id: reservation_flavor_id
|
||||
- reservation.server_group_id: reservation_server_group_id
|
||||
- reservation.aggregate_id: reservation_aggregate_id
|
||||
|
@ -114,6 +114,7 @@ class VirtualInstancePlugin(base.BasePlugin, nova.NovaClientWrapper):
|
||||
return max_vcpus, max_memory, max_disk
|
||||
|
||||
def query_available_hosts(self, cpus=None, memory=None, disk=None,
|
||||
resource_properties=None,
|
||||
start_date=None, end_date=None,
|
||||
excludes_res=None):
|
||||
"""Query hosts that are available for a reservation.
|
||||
@ -129,8 +130,10 @@ class VirtualInstancePlugin(base.BasePlugin, nova.NovaClientWrapper):
|
||||
|
||||
filters = plugins_utils.convert_requirements(flavor_definitions)
|
||||
|
||||
hosts = db_api.reservable_host_get_all_by_queries(filters)
|
||||
if resource_properties:
|
||||
filters += plugins_utils.convert_requirements(resource_properties)
|
||||
|
||||
hosts = db_api.reservable_host_get_all_by_queries(filters)
|
||||
free_hosts, reserved_hosts = \
|
||||
self.filter_hosts_by_reservation(hosts, start_date, end_date,
|
||||
excludes_res)
|
||||
@ -168,6 +171,7 @@ class VirtualInstancePlugin(base.BasePlugin, nova.NovaClientWrapper):
|
||||
'cpus': values['vcpus'],
|
||||
'memory': values['memory_mb'],
|
||||
'disk': values['disk_gb'],
|
||||
'resource_properties': values['resource_properties'],
|
||||
'start_date': values['start_date'],
|
||||
'end_date': values['end_date']
|
||||
}
|
||||
@ -299,7 +303,8 @@ class VirtualInstancePlugin(base.BasePlugin, nova.NovaClientWrapper):
|
||||
|
||||
def validate_reservation_param(self, values):
|
||||
marshall_attributes = set(['vcpus', 'memory_mb', 'disk_gb',
|
||||
'amount', 'affinity'])
|
||||
'amount', 'affinity',
|
||||
'resource_properties'])
|
||||
missing_attr = marshall_attributes - set(values.keys())
|
||||
if missing_attr:
|
||||
raise mgr_exceptions.MissingParameter(param=','.join(missing_attr))
|
||||
@ -327,6 +332,7 @@ class VirtualInstancePlugin(base.BasePlugin, nova.NovaClientWrapper):
|
||||
'disk_gb': values['disk_gb'],
|
||||
'amount': values['amount'],
|
||||
'affinity': bool_from_string(values['affinity']),
|
||||
'resource_properties': values['resource_properties']
|
||||
}
|
||||
instance_reservation = db_api.instance_reservation_create(
|
||||
instance_reservation_val)
|
||||
@ -383,7 +389,8 @@ class VirtualInstancePlugin(base.BasePlugin, nova.NovaClientWrapper):
|
||||
reservation = db_api.reservation_get(reservation_id)
|
||||
lease = db_api.lease_get(reservation['lease_id'])
|
||||
|
||||
updatable = ['vcpus', 'memory_mb', 'disk_gb', 'affinity', 'amount']
|
||||
updatable = ['vcpus', 'memory_mb', 'disk_gb', 'affinity', 'amount',
|
||||
'resource_properties']
|
||||
if (not any([k in updatable for k in new_values.keys()])
|
||||
and new_values['start_date'] >= lease['start_date']
|
||||
and new_values['end_date'] <= lease['end_date']):
|
||||
@ -529,7 +536,8 @@ class VirtualInstancePlugin(base.BasePlugin, nova.NovaClientWrapper):
|
||||
values['start_date'] = max(datetime.datetime.utcnow(),
|
||||
lease['start_date'])
|
||||
values['end_date'] = lease['end_date']
|
||||
specs = ['vcpus', 'memory_mb', 'disk_gb', 'affinity', 'amount']
|
||||
specs = ['vcpus', 'memory_mb', 'disk_gb', 'affinity', 'amount',
|
||||
'resource_properties']
|
||||
for key in specs:
|
||||
values[key] = reservation[key]
|
||||
changed_hosts = self.pickup_hosts(reservation['id'], values)
|
||||
|
@ -36,10 +36,12 @@ class TestVirtualInstancePlugin(tests.TestCase):
|
||||
super(TestVirtualInstancePlugin, self).setUp()
|
||||
|
||||
def get_input_values(self, vcpus, memory, disk, amount, affinity,
|
||||
start, end, lease_id):
|
||||
return {'vcpus': vcpus, 'memory_mb': memory, 'disk_gb': disk,
|
||||
'amount': amount, 'affinity': affinity, 'start_date': start,
|
||||
'end_date': end, 'lease_id': lease_id}
|
||||
start, end, lease_id, resource_properties):
|
||||
values = {'vcpus': vcpus, 'memory_mb': memory, 'disk_gb': disk,
|
||||
'amount': amount, 'affinity': affinity, 'start_date': start,
|
||||
'end_date': end, 'lease_id': lease_id,
|
||||
'resource_properties': resource_properties}
|
||||
return values
|
||||
|
||||
def generate_host_info(self, id, vcpus, memory, disk):
|
||||
return {'id': id, 'vcpus': vcpus,
|
||||
@ -93,7 +95,7 @@ class TestVirtualInstancePlugin(tests.TestCase):
|
||||
|
||||
inputs = self.get_input_values(2, 4018, 10, 1, False,
|
||||
'2030-01-01 08:00', '2030-01-01 08:00',
|
||||
'lease-1')
|
||||
'lease-1', '')
|
||||
|
||||
expected_ret = 'instance-reservation-id1'
|
||||
|
||||
@ -102,7 +104,8 @@ class TestVirtualInstancePlugin(tests.TestCase):
|
||||
self.assertEqual(expected_ret, ret)
|
||||
pickup_hosts_value = {}
|
||||
for key in ['vcpus', 'memory_mb', 'disk_gb', 'amount', 'affinity',
|
||||
'lease_id', 'start_date', 'end_date']:
|
||||
'lease_id', 'start_date', 'end_date',
|
||||
'resource_properties']:
|
||||
pickup_hosts_value[key] = inputs[key]
|
||||
mock_pickup_hosts.assert_called_once_with('res_id1',
|
||||
pickup_hosts_value)
|
||||
@ -122,7 +125,7 @@ class TestVirtualInstancePlugin(tests.TestCase):
|
||||
plugin = instance_plugin.VirtualInstancePlugin()
|
||||
inputs = self.get_input_values(2, 4018, 10, 1, True,
|
||||
'2030-01-01 08:00', '2030-01-01 08:00',
|
||||
'lease-1')
|
||||
'lease-1', '')
|
||||
self.assertRaises(exceptions.BlazarException, plugin.reserve_resource,
|
||||
'reservation_id', inputs)
|
||||
self.assertRaises(exceptions.BlazarException,
|
||||
@ -197,6 +200,7 @@ class TestVirtualInstancePlugin(tests.TestCase):
|
||||
'memory_mb': 1024,
|
||||
'disk_gb': 20,
|
||||
'amount': 2,
|
||||
'resource_properties': '',
|
||||
'start_date': '2030-01-01 08:00',
|
||||
'end_date': '2030-01-01 12:00'
|
||||
}
|
||||
@ -238,6 +242,7 @@ class TestVirtualInstancePlugin(tests.TestCase):
|
||||
'memory_mb': 1024,
|
||||
'disk_gb': 20,
|
||||
'amount': 2,
|
||||
'resource_properties': '',
|
||||
'start_date': '2030-01-01 08:00',
|
||||
'end_date': '2030-01-01 12:00'
|
||||
}
|
||||
@ -291,6 +296,7 @@ class TestVirtualInstancePlugin(tests.TestCase):
|
||||
'memory_mb': 1024,
|
||||
'disk_gb': 20,
|
||||
'amount': 2,
|
||||
'resource_properties': '',
|
||||
'start_date': '2030-01-01 08:00',
|
||||
'end_date': '2030-01-01 12:00'
|
||||
}
|
||||
@ -344,6 +350,7 @@ class TestVirtualInstancePlugin(tests.TestCase):
|
||||
'memory_mb': 1024,
|
||||
'disk_gb': 20,
|
||||
'amount': 2,
|
||||
'resource_properties': '',
|
||||
'start_date': '2030-01-01 08:00',
|
||||
'end_date': '2030-01-01 12:00'
|
||||
}
|
||||
@ -563,22 +570,38 @@ class TestVirtualInstancePlugin(tests.TestCase):
|
||||
# case: new amount is less than old amount
|
||||
values = self.get_input_values(1, 1024, 10, 1, False,
|
||||
'2020-07-01 10:00', '2020-07-01 11:00',
|
||||
'lease-1')
|
||||
'lease-1', '')
|
||||
expect = {'added': set([]),
|
||||
'removed': set(['host-id1', 'host-id2', 'host-id3'])}
|
||||
ret = plugin.pickup_hosts(reservation['id'], values)
|
||||
self.assertEqual(expect['added'], ret['added'])
|
||||
self.assertTrue(len(ret['removed']) == 2)
|
||||
self.assertTrue(all([h in expect['removed'] for h in ret['removed']]))
|
||||
query_params = {
|
||||
'cpus': 1, 'memory': 1024, 'disk': 10,
|
||||
'resource_properties': '',
|
||||
'start_date': '2020-07-01 10:00',
|
||||
'end_date': '2020-07-01 11:00',
|
||||
'excludes_res': ['reservation-id1']
|
||||
}
|
||||
mock_query_available.assert_called_with(**query_params)
|
||||
|
||||
# case: new amount is same but change allocations
|
||||
values = self.get_input_values(1, 1024, 10, 3, False,
|
||||
'2020-07-01 10:00', '2020-07-01 11:00',
|
||||
'lease-1')
|
||||
'lease-1', '["==", "key1", "value1"]')
|
||||
expect = {'added': set(['host-id4']), 'removed': set(['host-id1'])}
|
||||
ret = plugin.pickup_hosts(reservation['id'], values)
|
||||
self.assertEqual(expect['added'], ret['added'])
|
||||
self.assertEqual(expect['removed'], ret['removed'])
|
||||
query_params = {
|
||||
'cpus': 1, 'memory': 1024, 'disk': 10,
|
||||
'resource_properties': '["==", "key1", "value1"]',
|
||||
'start_date': '2020-07-01 10:00',
|
||||
'end_date': '2020-07-01 11:00',
|
||||
'excludes_res': ['reservation-id1']
|
||||
}
|
||||
mock_query_available.assert_called_with(**query_params)
|
||||
|
||||
# case: new amount is greater than old amount
|
||||
mock_query_available.return_value = [
|
||||
@ -589,11 +612,19 @@ class TestVirtualInstancePlugin(tests.TestCase):
|
||||
|
||||
values = self.get_input_values(1, 1024, 10, 4, False,
|
||||
'2020-07-01 10:00', '2020-07-01 11:00',
|
||||
'lease-1')
|
||||
'lease-1', '')
|
||||
expect = {'added': set(['host-id4']), 'removed': set([])}
|
||||
ret = plugin.pickup_hosts(reservation['id'], values)
|
||||
self.assertEqual(expect['added'], ret['added'])
|
||||
self.assertEqual(expect['removed'], ret['removed'])
|
||||
query_params = {
|
||||
'cpus': 1, 'memory': 1024, 'disk': 10,
|
||||
'resource_properties': '',
|
||||
'start_date': '2020-07-01 10:00',
|
||||
'end_date': '2020-07-01 11:00',
|
||||
'excludes_res': ['reservation-id1']
|
||||
}
|
||||
mock_query_available.assert_called_with(**query_params)
|
||||
|
||||
def test_update_resources(self):
|
||||
reservation = {
|
||||
@ -673,7 +704,8 @@ class TestVirtualInstancePlugin(tests.TestCase):
|
||||
'lease_id': 'lease-id1',
|
||||
'resource_id': 'instance-reservation-id1',
|
||||
'vcpus': 2, 'memory_mb': 1024, 'disk_gb': 100,
|
||||
'amount': 2, 'affinity': False}
|
||||
'amount': 2, 'affinity': False,
|
||||
'resource_properties': ''}
|
||||
mock_reservation_get = self.patch(db_api, 'reservation_get')
|
||||
mock_reservation_get.return_value = old_reservation
|
||||
|
||||
@ -700,11 +732,11 @@ class TestVirtualInstancePlugin(tests.TestCase):
|
||||
mock_pickup_hosts.assert_called_once_with(
|
||||
'reservation-id1',
|
||||
{'vcpus': 4, 'memory_mb': 1024, 'disk_gb': 200,
|
||||
'amount': 2, 'affinity': False})
|
||||
'amount': 2, 'affinity': False, 'resource_properties': ''})
|
||||
mock_inst_update.assert_called_once_with(
|
||||
'instance-reservation-id1',
|
||||
{'vcpus': 4, 'memory_mb': 1024, 'disk_gb': 200,
|
||||
'amount': 2, 'affinity': False})
|
||||
'amount': 2, 'affinity': False, 'resource_properties': ''})
|
||||
mock_update_alloc.assert_called_once_with(set(['host-id1']),
|
||||
set(['host-id2']),
|
||||
'reservation-id1')
|
||||
@ -847,6 +879,7 @@ class TestVirtualInstancePlugin(tests.TestCase):
|
||||
'aggregate_id': 'agg-1',
|
||||
'affinity': False,
|
||||
'amount': 3,
|
||||
'resource_properties': '',
|
||||
'computehost_allocations': [{
|
||||
'id': 'alloc-1', 'compute_host_id': failed_host['id'],
|
||||
'reservation_id': 'rsrv-1'
|
||||
@ -880,6 +913,7 @@ class TestVirtualInstancePlugin(tests.TestCase):
|
||||
'aggregate_id': 'agg-1',
|
||||
'affinity': False,
|
||||
'amount': 3,
|
||||
'resource_properties': '',
|
||||
'computehost_allocations': [{
|
||||
'id': 'alloc-1', 'compute_host_id': failed_host['id'],
|
||||
'reservation_id': 'rsrv-1'
|
||||
@ -990,7 +1024,8 @@ class TestVirtualInstancePlugin(tests.TestCase):
|
||||
'disk_gb': 256,
|
||||
'aggregate_id': 'agg-1',
|
||||
'affinity': False,
|
||||
'amount': 3
|
||||
'amount': 3,
|
||||
'resource_properties': ''
|
||||
}
|
||||
dummy_lease = {
|
||||
'name': 'lease-name',
|
||||
@ -1039,8 +1074,8 @@ class TestVirtualInstancePlugin(tests.TestCase):
|
||||
'disk_gb': 256,
|
||||
'aggregate_id': 'agg-1',
|
||||
'affinity': False,
|
||||
'amount': 3
|
||||
}
|
||||
'amount': 3,
|
||||
'resource_properties': ''}
|
||||
dummy_lease = {
|
||||
'name': 'lease-name',
|
||||
'start_date': datetime.datetime(2020, 1, 1, 12, 00),
|
||||
@ -1098,7 +1133,8 @@ class TestVirtualInstancePlugin(tests.TestCase):
|
||||
'disk_gb': 256,
|
||||
'aggregate_id': 'agg-1',
|
||||
'affinity': False,
|
||||
'amount': 3
|
||||
'amount': 3,
|
||||
'resource_properties': ''
|
||||
}
|
||||
dummy_lease = {
|
||||
'name': 'lease-name',
|
||||
|
@ -18,7 +18,8 @@
|
||||
"vcpus": 2,
|
||||
"memory_mb": 4096,
|
||||
"disk_gb": 100,
|
||||
"affinity": false
|
||||
"affinity": false,
|
||||
"resource_properties": ""
|
||||
}
|
||||
],
|
||||
"events": []
|
||||
|
@ -41,6 +41,7 @@
|
||||
"memory_mb": 4096,
|
||||
"disk_gb": 100,
|
||||
"affinity": false,
|
||||
"resource_properties": "",
|
||||
"flavor_id": "ddc45423-f863-4e4e-8e7a-51d27cfec962",
|
||||
"server_group_id": "33cdfc42-5a04-4fcc-b190-1abebaa056bb",
|
||||
"aggregate_id": 11,
|
||||
|
@ -41,6 +41,7 @@
|
||||
"memory_mb": 4096,
|
||||
"disk_gb": 100,
|
||||
"affinity": false,
|
||||
"resource_properties": "",
|
||||
"flavor_id": "ddc45423-f863-4e4e-8e7a-51d27cfec962",
|
||||
"server_group_id": "33cdfc42-5a04-4fcc-b190-1abebaa056bb",
|
||||
"aggregate_id": 11,
|
||||
|
@ -42,6 +42,7 @@
|
||||
"memory_mb": 4096,
|
||||
"disk_gb": 100,
|
||||
"affinity": false,
|
||||
"resource_properties": "",
|
||||
"flavor_id": "ddc45423-f863-4e4e-8e7a-51d27cfec962",
|
||||
"server_group_id": "33cdfc42-5a04-4fcc-b190-1abebaa056bb",
|
||||
"aggregate_id": 11,
|
||||
|
@ -41,6 +41,7 @@
|
||||
"memory_mb": 4096,
|
||||
"disk_gb": 100,
|
||||
"affinity": false,
|
||||
"resource_properties": "",
|
||||
"flavor_id": "ddc45423-f863-4e4e-8e7a-51d27cfec962",
|
||||
"server_group_id": "33cdfc42-5a04-4fcc-b190-1abebaa056bb",
|
||||
"aggregate_id": 11,
|
||||
|
Loading…
x
Reference in New Issue
Block a user