
For now, policy file unaccessible due to access permission leads to silent failure without any notifictaion. Side effects of it are also affected by policy caching and might be quite confusing, like periodic disappearing of Horizon panels. Proposed patch added handling of such errors. Closes-bug: #1836390 Change-Id: I0d67b6e7c2dcaa63d6bb807f013e5e7334efc715
82 lines
2.6 KiB
Python
82 lines
2.6 KiB
Python
# 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.
|
|
|
|
import errno
|
|
import logging
|
|
import os
|
|
|
|
from oslo_config import cfg
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
def read_cached_file(cache, filename, force_reload=False):
|
|
"""Read from a file if it has been modified.
|
|
|
|
:param cache: dictionary to hold opaque cache.
|
|
:param filename: the file path to read.
|
|
:param force_reload: Whether to reload the file.
|
|
:returns: A tuple with a boolean specifying if the data is fresh
|
|
or not.
|
|
"""
|
|
|
|
if force_reload:
|
|
delete_cached_file(cache, filename)
|
|
|
|
reloaded = False
|
|
try:
|
|
mtime = os.path.getmtime(filename)
|
|
except OSError as err:
|
|
msg = err.strerror
|
|
LOG.error('Config file not found %(filename)s: %(msg)s',
|
|
{'filename': filename, 'msg': msg})
|
|
return True, {}
|
|
|
|
cache_info = cache.setdefault(filename, {})
|
|
|
|
if not cache_info or mtime > cache_info.get('mtime', 0):
|
|
LOG.debug("Reloading cached file %s", filename)
|
|
try:
|
|
with open(filename) as fap:
|
|
cache_info['data'] = fap.read()
|
|
except IOError as err:
|
|
msg = err.strerror
|
|
err_code = err.errno
|
|
LOG.error('IO error loading %(filename)s: %(msg)s',
|
|
{'filename': filename, 'msg': msg})
|
|
if err_code == errno.EACCES:
|
|
raise cfg.ConfigFilesPermissionDeniedError((filename,))
|
|
except OSError as err:
|
|
msg = err.strerror
|
|
LOG.error('Config file not found %(filename)s: %(msg)s',
|
|
{'filename': filename, 'msg': msg})
|
|
raise cfg.ConfigFilesNotFoundError((filename,))
|
|
cache_info['mtime'] = mtime
|
|
reloaded = True
|
|
return (reloaded, cache_info['data'])
|
|
|
|
|
|
def delete_cached_file(cache, filename):
|
|
"""Delete cached file if present.
|
|
|
|
:param cache: dictionary to hold opaque cache.
|
|
:param filename: filename to delete
|
|
"""
|
|
|
|
try:
|
|
del cache[filename]
|
|
except KeyError:
|
|
pass
|