Only create a server group when affinity is set
Also adds docs so a user can find this behaviour easily. Closes-Bug: #2071832 Change-Id: Iea3c4164f3e893c355ec21653f2e8f0e848941f0
This commit is contained in:
parent
3999bf1fb7
commit
c80d519998
@ -317,7 +317,8 @@ class VirtualInstancePlugin(base.BasePlugin, nova.NovaClientWrapper):
|
||||
|
||||
return {'added': added_host_ids, 'removed': removed_host_ids}
|
||||
|
||||
def _create_flavor(self, reservation_id, vcpus, memory, disk, group_id):
|
||||
def _create_flavor(self, reservation_id, vcpus, memory, disk,
|
||||
group_id=None):
|
||||
flavor_details = {
|
||||
'flavorid': reservation_id,
|
||||
'name': RESERVATION_PREFIX + ":" + reservation_id,
|
||||
@ -333,9 +334,10 @@ class VirtualInstancePlugin(base.BasePlugin, nova.NovaClientWrapper):
|
||||
reservation_rc = "resources:CUSTOM_RESERVATION_" + rsv_id_rc_format
|
||||
extra_specs = {
|
||||
FLAVOR_EXTRA_SPEC: reservation_id,
|
||||
"affinity_id": group_id,
|
||||
reservation_rc: "1"
|
||||
}
|
||||
if group_id is not None:
|
||||
extra_specs["affinity_id"] = group_id
|
||||
reserved_flavor.set_keys(extra_specs)
|
||||
|
||||
return reserved_flavor
|
||||
@ -346,23 +348,31 @@ class VirtualInstancePlugin(base.BasePlugin, nova.NovaClientWrapper):
|
||||
ctx = context.current()
|
||||
user_client = nova.NovaClientWrapper()
|
||||
|
||||
reserved_group = user_client.nova.server_groups.create(
|
||||
RESERVATION_PREFIX + ':' + reservation_id,
|
||||
'affinity' if inst_reservation['affinity'] else 'anti-affinity'
|
||||
)
|
||||
flavor_args = {
|
||||
'reservation_id': reservation_id,
|
||||
'vcpus': inst_reservation['vcpus'],
|
||||
'memory': inst_reservation['memory_mb'],
|
||||
'disk': inst_reservation['disk_gb']
|
||||
}
|
||||
|
||||
reserved_flavor = self._create_flavor(reservation_id,
|
||||
inst_reservation['vcpus'],
|
||||
inst_reservation['memory_mb'],
|
||||
inst_reservation['disk_gb'],
|
||||
reserved_group.id)
|
||||
|
||||
pool = nova.ReservationPool()
|
||||
pool_metadata = {
|
||||
RESERVATION_PREFIX: reservation_id,
|
||||
'filter_tenant_id': ctx.project_id,
|
||||
'affinity_id': reserved_group.id
|
||||
}
|
||||
|
||||
if inst_reservation['affinity'] is not None:
|
||||
reserved_group = user_client.nova.server_groups.create(
|
||||
RESERVATION_PREFIX + ':' + reservation_id,
|
||||
'affinity' if inst_reservation['affinity'] else 'anti-affinity'
|
||||
)
|
||||
flavor_args['group_id'] = reserved_group.id
|
||||
pool_metadata['affinity_id'] = reserved_group.id
|
||||
else:
|
||||
reserved_group = None
|
||||
|
||||
reserved_flavor = self._create_flavor(**flavor_args)
|
||||
|
||||
pool = nova.ReservationPool()
|
||||
agg = pool.create(name=reservation_id, metadata=pool_metadata)
|
||||
|
||||
self.placement_client.create_reservation_class(reservation_id)
|
||||
@ -483,9 +493,10 @@ class VirtualInstancePlugin(base.BasePlugin, nova.NovaClientWrapper):
|
||||
self.cleanup_resources(instance_reservation)
|
||||
raise mgr_exceptions.NovaClientError()
|
||||
|
||||
server_group_id = group.id if group is not None else None
|
||||
db_api.instance_reservation_update(instance_reservation['id'],
|
||||
{'flavor_id': flavor.id,
|
||||
'server_group_id': group.id,
|
||||
'server_group_id': server_group_id,
|
||||
'aggregate_id': pool.id})
|
||||
|
||||
return instance_reservation['id']
|
||||
|
@ -410,6 +410,61 @@ class TestVirtualInstancePlugin(tests.TestCase):
|
||||
expected_query = ['vcpus >= 2', 'memory_mb >= 2048', 'local_gb >= 100']
|
||||
mock_host_get_query.assert_called_once_with(expected_query)
|
||||
|
||||
def test_pickup_host_with_anti_affinity(self):
|
||||
def fake_get_reservation_by_host(host_id, start, end):
|
||||
if host_id in ['host-1', 'host-3']:
|
||||
return [
|
||||
{'id': '1',
|
||||
'resource_type': instances.RESOURCE_TYPE},
|
||||
{'id': '2',
|
||||
'resource_type': instances.RESOURCE_TYPE}
|
||||
]
|
||||
else:
|
||||
return []
|
||||
|
||||
plugin = instance_plugin.VirtualInstancePlugin()
|
||||
|
||||
mock_host_allocation_get = self.patch(
|
||||
db_api, 'host_allocation_get_all_by_values')
|
||||
mock_host_allocation_get.return_value = []
|
||||
|
||||
mock_host_get_query = self.patch(db_api,
|
||||
'reservable_host_get_all_by_queries')
|
||||
hosts_list = [self.generate_host_info('host-1', 8, 8192, 1000),
|
||||
self.generate_host_info('host-2', 2, 2048, 500)]
|
||||
mock_host_get_query.return_value = hosts_list
|
||||
|
||||
mock_get_reservations = self.patch(db_utils,
|
||||
'get_reservations_by_host_id')
|
||||
|
||||
mock_get_reservations.side_effect = fake_get_reservation_by_host
|
||||
|
||||
mock_max_usages = self.patch(plugin, 'max_usages')
|
||||
mock_max_usages.return_value = (0, 0, 0)
|
||||
|
||||
mock_reservation_get = self.patch(db_api, 'reservation_get')
|
||||
mock_reservation_get.return_value = {
|
||||
'status': 'pending'
|
||||
}
|
||||
|
||||
params = {
|
||||
'vcpus': 2,
|
||||
'memory_mb': 2048,
|
||||
'disk_gb': 100,
|
||||
'amount': 2,
|
||||
'affinity': False,
|
||||
'resource_properties': '',
|
||||
'start_date': datetime.datetime(2030, 1, 1, 8, 00),
|
||||
'end_date': datetime.datetime(2030, 1, 1, 12, 00)
|
||||
}
|
||||
|
||||
expected = {'added': ['host-1', 'host-2'], 'removed': []}
|
||||
ret = plugin.pickup_hosts('reservation-id1', params)
|
||||
|
||||
self.assertEqual(expected, ret)
|
||||
expected_query = ['vcpus >= 2', 'memory_mb >= 2048', 'local_gb >= 100']
|
||||
mock_host_get_query.assert_called_once_with(expected_query)
|
||||
|
||||
@ddt.data('None', 'none', None)
|
||||
def test_pickup_host_with_no_affinity(self, value):
|
||||
def fake_get_reservation_by_host(host_id, start, end):
|
||||
|
@ -166,3 +166,20 @@ Result:
|
||||
openstack server create --flavor db83d6fd-c69c-4259-92cf-012db2e55a58 --image <image> --network <network> <server-name>
|
||||
|
||||
..
|
||||
|
||||
|
||||
Affinity
|
||||
--------
|
||||
|
||||
A lease can be created with the optional ``--affinity`` parameter. This
|
||||
provides the following behavior:
|
||||
|
||||
* ``affinity=True``: Instances will be deployed on the same host for this
|
||||
reservation, by adding them to a server group with an affinity policy.
|
||||
|
||||
* ``affinity=False``: Instances will be deployed on different hosts for this
|
||||
reservation, by adding them to a server group with an anti-affinity policy.
|
||||
|
||||
* ``affinity=None`` (default): Instances can be deployed on any host,
|
||||
regardless of other instances in this reservation. No server group is
|
||||
created.
|
||||
|
@ -0,0 +1,14 @@
|
||||
---
|
||||
upgrade:
|
||||
- |
|
||||
Instance reservations will no longer create a server group when the
|
||||
``affinity`` parameter is not set. This means that instances can be
|
||||
deployed on any host. To achieve the old behaviour, you must now explicity
|
||||
set ``--affinity=false``.
|
||||
`LP#2071832 <https://launchpad.net/bugs/2071832>`__
|
||||
fixes:
|
||||
- |
|
||||
Instance reservations will no longer create a server group when the
|
||||
``affinity`` parameter is not set. This means that instances can be
|
||||
deployed on any host.
|
||||
`LP#2071832 <https://launchpad.net/bugs/2071832>`__
|
Loading…
Reference in New Issue
Block a user