Add cleaning time

This patch adds a margin between the end of a lease and the start of the
next lease. The length of the margin can be configured with the new
configuration option 'cleaning_time'.

Note that it does not actually change start/end_lease time, but just
takes into account the margin when looking for available resources.

Implements: blueprint cleaning-time-allowance
Change-Id: I7de05a65c2221c1eb7c5b2f65bec58d6a48b2085
This commit is contained in:
Hiroaki Kobayashi 2018-06-13 14:11:19 +09:00
parent 72202c9fd3
commit 513bde4c61
6 changed files with 76 additions and 15 deletions

View File

@ -72,8 +72,18 @@ api_opts = [
help='Deploy the v1 API.'),
]
lease_opts = [
cfg.IntOpt('cleaning_time',
default=0,
min=0,
help='The minimum interval [minutes] between the end of a '
'lease and the start of the next lease for the same '
'resource. This interval is used for cleanup.')
]
CONF = cfg.CONF
CONF.register_cli_opts(cli_opts)
CONF.register_opts(os_opts)
CONF.register_opts(api_opts)
CONF.register_opts(lease_opts)
logging.register_options(cfg.CONF)

View File

@ -133,9 +133,11 @@ class VirtualInstancePlugin(base.BasePlugin, nova.NovaClientWrapper):
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)
free_hosts, reserved_hosts = self.filter_hosts_by_reservation(
hosts,
start_date - datetime.timedelta(minutes=CONF.cleaning_time),
end_date + datetime.timedelta(minutes=CONF.cleaning_time),
excludes_res)
available_hosts = []
for host_info in reserved_hosts:

View File

@ -495,6 +495,11 @@ class PhysicalHostPlugin(base.BasePlugin, nova.NovaClientWrapper):
allocated_host_ids = []
not_allocated_host_ids = []
filter_array = []
start_date_with_margin = start_date - datetime.timedelta(
minutes=CONF.cleaning_time)
end_date_with_margin = end_date + datetime.timedelta(
minutes=CONF.cleaning_time)
# TODO(frossigneux) support "or" operator
if hypervisor_properties:
filter_array = plugins_utils.convert_requirements(
@ -508,11 +513,11 @@ class PhysicalHostPlugin(base.BasePlugin, nova.NovaClientWrapper):
not_allocated_host_ids.append(host['id'])
elif db_utils.get_free_periods(
host['id'],
start_date,
end_date,
end_date - start_date,
start_date_with_margin,
end_date_with_margin,
end_date_with_margin - start_date_with_margin
) == [
(start_date, end_date),
(start_date_with_margin, end_date_with_margin),
]:
allocated_host_ids.append(host['id'])
if len(not_allocated_host_ids) >= int(min_host):

View File

@ -219,8 +219,8 @@ class TestVirtualInstancePlugin(tests.TestCase):
'disk_gb': 20,
'amount': 2,
'resource_properties': '',
'start_date': '2030-01-01 08:00',
'end_date': '2030-01-01 12:00'
'start_date': datetime.datetime(2030, 1, 1, 8, 00),
'end_date': datetime.datetime(2030, 1, 1, 12, 00)
}
expected = {'added': set(['host-2', 'host-3']), 'removed': set([])}
ret = plugin.pickup_hosts('reservation-id1', values)
@ -261,8 +261,8 @@ class TestVirtualInstancePlugin(tests.TestCase):
'disk_gb': 20,
'amount': 2,
'resource_properties': '',
'start_date': '2030-01-01 08:00',
'end_date': '2030-01-01 12:00'
'start_date': datetime.datetime(2030, 1, 1, 8, 00),
'end_date': datetime.datetime(2030, 1, 1, 12, 00),
}
expected = {'added': set(['host-1', 'host-2']), 'removed': set([])}
ret = plugin.pickup_hosts('reservation-id1', values)
@ -315,8 +315,8 @@ class TestVirtualInstancePlugin(tests.TestCase):
'disk_gb': 20,
'amount': 2,
'resource_properties': '',
'start_date': '2030-01-01 08:00',
'end_date': '2030-01-01 12:00'
'start_date': datetime.datetime(2030, 1, 1, 8, 00),
'end_date': datetime.datetime(2030, 1, 1, 12, 00)
}
expected = {'added': set(['host-1', 'host-3']), 'removed': set([])}
@ -369,8 +369,8 @@ class TestVirtualInstancePlugin(tests.TestCase):
'disk_gb': 20,
'amount': 2,
'resource_properties': '',
'start_date': '2030-01-01 08:00',
'end_date': '2030-01-01 12:00'
'start_date': datetime.datetime(2030, 1, 1, 8, 00),
'end_date': datetime.datetime(2030, 1, 1, 12, 00)
}
hosts = plugin.pickup_hosts('reservation-id1', values)

View File

@ -1796,6 +1796,38 @@ class PhysicalHostPluginTestCase(tests.TestCase):
datetime.datetime(2013, 12, 19, 21, 00))
self.assertEqual(['host1', 'host2', 'host3'], result)
def test_matching_hosts_allocated_hosts_with_cleaning_time(self):
def host_allocation_get_all_by_values(**kwargs):
if kwargs['compute_host_id'] == 'host1':
return True
self.cfg.CONF.set_override('cleaning_time', '5')
host_get = self.patch(
self.db_api,
'reservable_host_get_all_by_queries')
host_get.return_value = [
{'id': 'host1'},
{'id': 'host2'},
{'id': 'host3'},
]
host_get = self.patch(
self.db_api,
'host_allocation_get_all_by_values')
host_get.side_effect = host_allocation_get_all_by_values
host_get = self.patch(
self.db_utils,
'get_free_periods')
host_get.return_value = [
(datetime.datetime(2013, 12, 19, 20, 00)
- datetime.timedelta(minutes=5),
datetime.datetime(2013, 12, 19, 21, 00)
+ datetime.timedelta(minutes=5))
]
result = self.fake_phys_plugin._matching_hosts(
'[]', '[]', '3-3',
datetime.datetime(2013, 12, 19, 20, 00),
datetime.datetime(2013, 12, 19, 21, 00))
self.assertEqual(['host1', 'host2', 'host3'], result)
def test_matching_hosts_not_matching(self):
host_get = self.patch(
self.db_api,

View File

@ -0,0 +1,12 @@
---
features:
- |
A time margin for cleaning up resources between the end of a lease and the
start of the next lease is introduced. Leases are allocated to resources
only if they have enough spare time for cleaning up before and after the
lease. Note that this cleaning time is not included in the lease time, but
is taken into account when looking for available resources. The length of
cleaning time can be configured by the configuration option
**cleaning_time** in the [DEFAULT] section. The default value for this
option is **0**, in which case the behavior is the same as previous
releases.