diff --git a/nova/conf/scheduler.py b/nova/conf/scheduler.py index e872843be81e..2c93b744e9c3 100644 --- a/nova/conf/scheduler.py +++ b/nova/conf/scheduler.py @@ -37,21 +37,7 @@ Possible values: * A valid AMQP topic name """), - # TODO(sfinucan): Deprecate this option - cfg.StrOpt("scheduler_json_config_location", - default="", - help=""" -The absolute path to the scheduler configuration JSON file, if any. - -This file location is monitored by the scheduler for changes and reloads it if -needed. It is converted from JSON to a Python data structure, and passed into -the filtering and weighing functions of the scheduler, which can use it for -dynamic configuration. - -Possible values: - -* A valid file path, or an empty string -""")] +] scheduler_group = cfg.OptGroup(name="scheduler", title="Scheduler configuration") diff --git a/nova/scheduler/filter_scheduler.py b/nova/scheduler/filter_scheduler.py index c2defeb130da..da901e416b14 100644 --- a/nova/scheduler/filter_scheduler.py +++ b/nova/scheduler/filter_scheduler.py @@ -29,7 +29,6 @@ from nova import exception from nova.i18n import _ from nova import rpc from nova.scheduler import driver -from nova.scheduler import scheduler_options CONF = nova.conf.CONF @@ -40,7 +39,6 @@ class FilterScheduler(driver.Scheduler): """Scheduler that can be used for filtering and weighing.""" def __init__(self, *args, **kwargs): super(FilterScheduler, self).__init__(*args, **kwargs) - self.options = scheduler_options.SchedulerOptions() self.notifier = rpc.get_notifier('scheduler') def select_destinations(self, context, spec_obj): @@ -81,18 +79,12 @@ class FilterScheduler(driver.Scheduler): dict(request_spec=spec_obj.to_legacy_request_spec_dict())) return dests - def _get_configuration_options(self): - """Fetch options dictionary. Broken out for testing.""" - return self.options.get_configuration() - def _schedule(self, context, spec_obj): """Returns a list of hosts that meet the required specs, ordered by their fitness. """ elevated = context.elevated() - config_options = self._get_configuration_options() - # Find our local list of acceptable hosts by repeatedly # filtering and weighing our options. Each time we choose a # host, we virtually consume resources on it so subsequent @@ -105,8 +97,6 @@ class FilterScheduler(driver.Scheduler): selected_hosts = [] num_instances = spec_obj.num_instances - # NOTE(sbauza): Adding one field for any out-of-tree need - spec_obj.config_options = config_options for num in range(num_instances): # Filter local hosts based on requirements ... hosts = self.host_manager.get_filtered_hosts(hosts, diff --git a/nova/scheduler/scheduler_options.py b/nova/scheduler/scheduler_options.py deleted file mode 100644 index c31f9a5ae62f..000000000000 --- a/nova/scheduler/scheduler_options.py +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright (c) 2011 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -SchedulerOptions monitors a local .json file for changes and loads -it if needed. This file is converted to a data structure and passed -into the filtering and weighing functions which can use it for -dynamic configuration. -""" - -import datetime -import os - -from oslo_log import log as logging -from oslo_serialization import jsonutils -from oslo_utils import excutils -from oslo_utils import timeutils - -import nova.conf -from nova.i18n import _LE - - -CONF = nova.conf.CONF - -LOG = logging.getLogger(__name__) - - -class SchedulerOptions(object): - """SchedulerOptions monitors a local .json file for changes and loads it - if needed. This file is converted to a data structure and passed into - the filtering and weighing functions which can use it for dynamic - configuration. - """ - - def __init__(self): - super(SchedulerOptions, self).__init__() - self.data = {} - self.last_modified = None - self.last_checked = None - - def _get_file_handle(self, filename): - """Get file handle. Broken out for testing.""" - return open(filename) - - def _get_file_timestamp(self, filename): - """Get the last modified datetime. Broken out for testing.""" - try: - return os.path.getmtime(filename) - except os.error: - with excutils.save_and_reraise_exception(): - LOG.exception(_LE("Could not stat scheduler options file " - "%(filename)s"), - {'filename': filename}) - - def _load_file(self, handle): - """Decode the JSON file. Broken out for testing.""" - try: - return jsonutils.load(handle) - except ValueError: - LOG.exception(_LE("Could not decode scheduler options")) - return {} - - def _get_time_now(self): - """Get current UTC. Broken out for testing.""" - return timeutils.utcnow() - - def get_configuration(self, filename=None): - """Check the json file for changes and load it if needed.""" - if not filename: - filename = CONF.scheduler_json_config_location - if not filename: - return self.data - if self.last_checked: - now = self._get_time_now() - if now - self.last_checked < datetime.timedelta(minutes=5): - return self.data - - self.last_checked = self._get_time_now() - LOG.debug('Start to check scheduler configuration file at: %s', - self.last_checked) - - last_modified = self._get_file_timestamp(filename) - if (not last_modified or not self.last_modified or - last_modified > self.last_modified): - LOG.debug('Start to load scheduler configuration file which' - 'modified at: %s', last_modified) - self.data = self._load_file(self._get_file_handle(filename)) - self.last_modified = last_modified - if not self.data: - self.data = {} - - return self.data diff --git a/nova/tests/unit/scheduler/test_scheduler_options.py b/nova/tests/unit/scheduler/test_scheduler_options.py deleted file mode 100644 index 6f98713fa8d5..000000000000 --- a/nova/tests/unit/scheduler/test_scheduler_options.py +++ /dev/null @@ -1,163 +0,0 @@ -# Copyright 2011 OpenStack Foundation -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -""" -Tests For PickledScheduler. -""" - -import datetime - -from oslo_serialization import jsonutils -import six - -from nova.scheduler import scheduler_options -from nova import test - - -class FakeSchedulerOptions(scheduler_options.SchedulerOptions): - def __init__(self, last_checked, now, file_old, file_now, data, filedata): - super(FakeSchedulerOptions, self).__init__() - # Change internals ... - self.last_modified = file_old - self.last_checked = last_checked - self.data = data - - # For overrides ... - self._time_now = now - self._file_now = file_now - self._file_data = filedata - - self.file_was_loaded = False - - def _get_file_timestamp(self, filename): - return self._file_now - - def _get_file_handle(self, filename): - self.file_was_loaded = True - if six.PY3: - return six.BytesIO(self._file_data.encode('utf-8')) - return six.StringIO(self._file_data) - - def _get_time_now(self): - return self._time_now - - -class SchedulerOptionsTestCase(test.NoDBTestCase): - def test_get_configuration_first_time_no_flag(self): - last_checked = None - now = datetime.datetime(2012, 1, 1, 1, 1, 1) - file_old = None - file_now = datetime.datetime(2012, 1, 1, 1, 1, 1) - - data = dict(a=1, b=2, c=3) - jdata = jsonutils.dumps(data) - - fake = FakeSchedulerOptions(last_checked, now, file_old, file_now, - {}, jdata) - self.assertIsNone(fake.last_checked) - self.assertEqual({}, fake.get_configuration()) - self.assertFalse(fake.file_was_loaded) - self.assertIsNone(fake.last_checked) - - def test_get_configuration_first_time_empty_file(self): - last_checked = None - now = datetime.datetime(2012, 1, 1, 1, 1, 1) - file_old = None - file_now = datetime.datetime(2012, 1, 1, 1, 1, 1) - - jdata = "" - - fake = FakeSchedulerOptions(last_checked, now, file_old, file_now, - {}, jdata) - - self.assertIsNone(fake.last_checked) - self.assertEqual({}, fake.get_configuration('foo.json')) - self.assertTrue(fake.file_was_loaded) - self.assertEqual(now, fake.last_checked) - - def test_get_configuration_first_time_happy_day(self): - last_checked = None - now = datetime.datetime(2012, 1, 1, 1, 1, 1) - file_old = None - file_now = datetime.datetime(2012, 1, 1, 1, 1, 1) - - data = dict(a=1, b=2, c=3) - jdata = jsonutils.dumps(data) - - fake = FakeSchedulerOptions(last_checked, now, file_old, file_now, - {}, jdata) - self.assertIsNone(fake.last_checked) - self.assertEqual(data, fake.get_configuration('foo.json')) - self.assertTrue(fake.file_was_loaded) - self.assertEqual(now, fake.last_checked) - - def test_get_configuration_second_time_no_change(self): - last_checked = datetime.datetime(2011, 1, 1, 1, 1, 1) - now = datetime.datetime(2012, 1, 1, 1, 1, 1) - file_old = datetime.datetime(2012, 1, 1, 1, 1, 1) - file_now = datetime.datetime(2012, 1, 1, 1, 1, 1) - - data = dict(a=1, b=2, c=3) - jdata = jsonutils.dumps(data) - - fake = FakeSchedulerOptions(last_checked, now, file_old, file_now, - data, jdata) - - self.assertEqual(last_checked, fake.last_checked) - self.assertEqual(data, fake.get_configuration('foo.json')) - self.assertFalse(fake.file_was_loaded) - self.assertEqual(now, fake.last_checked) - - def test_get_configuration_second_time_too_fast(self): - # first check - last_checked = None - fisrt_now = datetime.datetime(2013, 1, 1, 1, 1, 2) - file_old = datetime.datetime(2012, 1, 1, 1, 1, 1) - file_now = datetime.datetime(2013, 1, 1, 1, 1, 1) - old_data = dict(a=1, b=2, c=3) - data = dict(a=11, b=12, c=13) - jdata = jsonutils.dumps(data) - fake = FakeSchedulerOptions(last_checked, fisrt_now, file_old, - file_now, old_data, jdata) - self.assertIsNone(fake.last_checked) - self.assertEqual(data, fake.get_configuration('foo.json')) - self.assertTrue(fake.file_was_loaded) - self.assertEqual(fisrt_now, fake.last_checked) - - # second time too fast, so won't check/load again - sec_now = datetime.datetime(2013, 1, 1, 1, 1, 3) - fake.file_was_loaded = False - fake._time_now = sec_now - fake._file_data = dict(a=21, b=22, c=23) - - self.assertEqual(data, fake.get_configuration('foo.json')) - self.assertFalse(fake.file_was_loaded) - self.assertEqual(fisrt_now, fake.last_checked) - - def test_get_configuration_second_time_change(self): - last_checked = datetime.datetime(2011, 1, 1, 1, 1, 1) - now = datetime.datetime(2012, 1, 1, 1, 1, 1) - file_old = datetime.datetime(2012, 1, 1, 1, 1, 1) - file_now = datetime.datetime(2013, 1, 1, 1, 1, 1) - - old_data = dict(a=1, b=2, c=3) - data = dict(a=11, b=12, c=13) - jdata = jsonutils.dumps(data) - - fake = FakeSchedulerOptions(last_checked, now, file_old, file_now, - old_data, jdata) - self.assertEqual(last_checked, fake.last_checked) - self.assertEqual(data, fake.get_configuration('foo.json')) - self.assertTrue(fake.file_was_loaded) - self.assertEqual(now, fake.last_checked) diff --git a/releasenotes/notes/remove-scheduler_json_config_location-option-c669e8c9867ce0fb.yaml b/releasenotes/notes/remove-scheduler_json_config_location-option-c669e8c9867ce0fb.yaml new file mode 100644 index 000000000000..0c38fb8a5621 --- /dev/null +++ b/releasenotes/notes/remove-scheduler_json_config_location-option-c669e8c9867ce0fb.yaml @@ -0,0 +1,5 @@ +--- +upgrade: + - | + The ``scheduler_json_config_location`` configuration option has not been + used in recent releases and has been removed.