conf: Remove 'scheduler_json_config_location'
The code that parses this file does nothing with the contents. Time to remove both the code and option. Change-Id: I228349110f9a9551776b18fbf8729a59ac7f810d Implements: bp centralize-config-options-ocata
This commit is contained in:
@@ -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")
|
||||
|
@@ -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,
|
||||
|
@@ -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
|
@@ -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)
|
@@ -0,0 +1,5 @@
|
||||
---
|
||||
upgrade:
|
||||
- |
|
||||
The ``scheduler_json_config_location`` configuration option has not been
|
||||
used in recent releases and has been removed.
|
Reference in New Issue
Block a user