Keep updating allocations for Ironic

When ironic updates the instance.flavor to require the new custom
resource class, we really need the allocations to get updated. Easiest
way to do that is to make the resource tracker keep updating allocations
for the ironic virt driver. This can be dropped once the transition to
custom resource classes is complete.

If we were not to claim the extra resources, placement will pick nodes
that already have instances running on them when you boot an instance
with a flavor that only requests the custom resource class. This should
be what all ironic flavors do, before the upgrade to queens is
performed.

Closes-Bug: #1724589

Change-Id: Ibbf65a8d817d359786abcdffa6358089ed1107f6
(cherry picked from commit 5c2b8675e3)
This commit is contained in:
John Garbutt 2017-10-18 17:05:43 +01:00 committed by Matt Riedemann
parent 8110ab1535
commit 842641c9b0
6 changed files with 57 additions and 6 deletions

View File

@ -1010,7 +1010,7 @@ class ResourceTracker(object):
continue
def _update_usage_from_instance(self, context, instance, nodename,
is_removed=False, has_ocata_computes=False):
is_removed=False, require_allocation_refresh=False):
"""Update usage for a single instance."""
uuid = instance['uuid']
@ -1038,10 +1038,9 @@ class ResourceTracker(object):
self.pci_tracker.update_pci_for_instance(context,
instance,
sign=sign)
if has_ocata_computes:
LOG.debug("We're on a Pike compute host in a deployment "
"with Ocata compute hosts. Auto-correcting "
"allocations to handle Ocata-style assumptions.")
if require_allocation_refresh:
LOG.debug("Auto-correcting allocations to handle Ocata "
"assumptions.")
self.reportclient.update_instance_allocation(cn, instance,
sign)
else:
@ -1135,10 +1134,16 @@ class ResourceTracker(object):
context, 'nova-compute')
has_ocata_computes = compute_version < 22
# Some drivers (ironic) still need the allocations to be
# fixed up, as they transition the way their inventory is reported.
require_allocation_refresh = (
has_ocata_computes or
self.driver.requires_allocation_refresh)
for instance in instances:
if instance.vm_state not in vm_states.ALLOW_RESOURCE_REMOVAL:
self._update_usage_from_instance(context, instance, nodename,
has_ocata_computes=has_ocata_computes)
require_allocation_refresh=require_allocation_refresh)
self._remove_deleted_instances_allocations(context, cn)

View File

@ -2571,6 +2571,40 @@ class TestUpdateUsageFromInstance(BaseTestCase):
self.assertEqual(-1024, cn.free_ram_mb)
self.assertEqual(-1, cn.free_disk_gb)
def test_update_usage_from_instances_refreshes_ironic(self):
self.rt.driver.requires_allocation_refresh = True
@mock.patch.object(self.rt,
'_remove_deleted_instances_allocations')
@mock.patch.object(self.rt, '_update_usage_from_instance')
@mock.patch('nova.objects.Service.get_minimum_version',
return_value=22)
def test(version_mock, uufi, rdia):
self.rt._update_usage_from_instances('ctxt', [self.instance],
_NODENAME)
uufi.assert_called_once_with('ctxt', self.instance, _NODENAME,
require_allocation_refresh=True)
test()
def test_update_usage_from_instances_no_refresh(self):
self.rt.driver.requires_allocation_refresh = False
@mock.patch.object(self.rt,
'_remove_deleted_instances_allocations')
@mock.patch.object(self.rt, '_update_usage_from_instance')
@mock.patch('nova.objects.Service.get_minimum_version',
return_value=22)
def test(version_mock, uufi, rdia):
self.rt._update_usage_from_instances('ctxt', [self.instance],
_NODENAME)
uufi.assert_called_once_with('ctxt', self.instance, _NODENAME,
require_allocation_refresh=False)
test()
@mock.patch('nova.scheduler.utils.resources_from_flavor')
def test_delete_allocation_for_evacuated_instance(
self, mock_resource_from_flavor):

View File

@ -134,6 +134,8 @@ class IronicDriverTestCase(test.NoDBTestCase):
'supports_migrate_to_same_host'],
'Driver capabilities for '
'\'supports_migrate_to_same_host\' is invalid')
self.assertTrue(self.driver.requires_allocation_refresh,
'Driver requires allocation refresh')
def test__get_hypervisor_type(self):
self.assertEqual('ironic', self.driver._get_hypervisor_type())

View File

@ -804,6 +804,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
'Driver capabilities for '
'\'supports_extend_volume\' '
'is invalid')
self.assertFalse(drvr.requires_allocation_refresh,
'Driver does not need allocation refresh')
def create_fake_libvirt_mock(self, **kwargs):
"""Defining mocks for LibvirtDriver(libvirt is not used)."""

View File

@ -132,6 +132,8 @@ class ComputeDriver(object):
"supports_extend_volume": False,
}
requires_allocation_refresh = False
def __init__(self, virtapi):
self.virtapi = virtapi
self._compute_event_callback = None

View File

@ -135,6 +135,12 @@ class IronicDriver(virt_driver.ComputeDriver):
"supports_attach_interface": True
}
# Needed for exiting instances to have allocations for custom resource
# class resources
# TODO(johngarbutt) we should remove this once the resource class
# migration has been completed.
requires_allocation_refresh = True
def __init__(self, virtapi, read_only=False):
super(IronicDriver, self).__init__(virtapi)
global ironic