From be623ffe3f98ffa0bf500b525ad8626bd25e43d9 Mon Sep 17 00:00:00 2001 From: Zhongyue Luo Date: Fri, 7 Jun 2013 15:23:54 +0800 Subject: [PATCH] Replace functions in utils with oslo.fileutils The following functions have moved to oslo. ensure_tree remove_path_on_error file_open delete_if_exists Replaced overlapping functions with the ones in fileutils Change-Id: Ib10a7ca2c72620f7f1df6c5bd4ef6c9cc4d8e913 --- cinder/brick/iscsi/iscsi.py | 3 +- cinder/image/image_utils.py | 11 ++-- cinder/openstack/common/fileutils.py | 75 ++++++++++++++++++++++++++++ cinder/utils.py | 51 ------------------- cinder/volume/drivers/lvm.py | 5 +- cinder/volume/drivers/rbd.py | 4 +- 6 files changed, 88 insertions(+), 61 deletions(-) diff --git a/cinder/brick/iscsi/iscsi.py b/cinder/brick/iscsi/iscsi.py index d09ae7ab5..4d3c90187 100644 --- a/cinder/brick/iscsi/iscsi.py +++ b/cinder/brick/iscsi/iscsi.py @@ -26,6 +26,7 @@ from oslo.config import cfg from cinder import exception from cinder import flags +from cinder.openstack.common import fileutils from cinder.openstack.common import log as logging from cinder import utils from cinder.volume import utils as volume_utils @@ -132,7 +133,7 @@ class TgtAdm(TargetAdmin): # Note(jdg) tid and lun aren't used by TgtAdm but remain for # compatibility - utils.ensure_tree(FLAGS.volumes_dir) + fileutils.ensure_tree(FLAGS.volumes_dir) vol_id = name.split(':')[1] if chap_auth is None: diff --git a/cinder/image/image_utils.py b/cinder/image/image_utils.py index 417f2b90c..9d0d4cce1 100644 --- a/cinder/image/image_utils.py +++ b/cinder/image/image_utils.py @@ -33,6 +33,7 @@ from oslo.config import cfg from cinder import exception from cinder import flags +from cinder.openstack.common import fileutils from cinder.openstack.common import log as logging from cinder import utils @@ -196,7 +197,7 @@ def fetch(context, image_service, image_id, path, _user_id, _project_id): # when it is added to glance. Right now there is no # auth checking in glance, so we assume that access was # checked before we got here. - with utils.remove_path_on_error(path): + with fileutils.remove_path_on_error(path): with open(path, "wb") as image_file: image_service.download(context, image_id, image_file) @@ -214,7 +215,7 @@ def fetch_to_raw(context, image_service, # it seeks. Maybe we can think of something for a future version. fd, tmp = tempfile.mkstemp(dir=FLAGS.image_conversion_dir) os.close(fd) - with utils.remove_path_on_error(tmp): + with fileutils.remove_path_on_error(tmp): fetch(context, image_service, image_id, tmp, user_id, project_id) data = qemu_img_info(tmp) @@ -256,7 +257,7 @@ def upload_volume(context, image_service, image_meta, volume_path): LOG.debug("%s was raw, no need to convert to %s" % (image_id, image_meta['disk_format'])) with utils.temporary_chown(volume_path): - with utils.file_open(volume_path) as image_file: + with fileutils.file_open(volume_path) as image_file: image_service.update(context, image_id, {}, image_file) return @@ -266,7 +267,7 @@ def upload_volume(context, image_service, image_meta, volume_path): fd, tmp = tempfile.mkstemp(dir=FLAGS.image_conversion_dir) os.close(fd) - with utils.remove_path_on_error(tmp): + with fileutils.remove_path_on_error(tmp): LOG.debug("%s was raw, converting to %s" % (image_id, image_meta['disk_format'])) convert_image(volume_path, tmp, image_meta['disk_format']) @@ -278,6 +279,6 @@ def upload_volume(context, image_service, image_meta, volume_path): reason=_("Converted to %(f1)s, but format is now %(f2)s") % {'f1': image_meta['disk_format'], 'f2': data.file_format}) - with utils.file_open(tmp) as image_file: + with fileutils.file_open(tmp) as image_file: image_service.update(context, image_id, {}, image_file) os.unlink(tmp) diff --git a/cinder/openstack/common/fileutils.py b/cinder/openstack/common/fileutils.py index b988ad03d..4301f2c13 100644 --- a/cinder/openstack/common/fileutils.py +++ b/cinder/openstack/common/fileutils.py @@ -16,9 +16,18 @@ # under the License. +import contextlib import errno import os +from cinder.openstack.common import excutils +from cinder.openstack.common.gettextutils import _ +from cinder.openstack.common import log as logging + +LOG = logging.getLogger(__name__) + +_FILE_CACHE = {} + def ensure_tree(path): """Create a directory (and any ancestor directories required) @@ -33,3 +42,69 @@ def ensure_tree(path): raise else: raise + + +def read_cached_file(filename, force_reload=False): + """Read from a file if it has been modified. + + :param force_reload: Whether to reload the file. + :returns: A tuple with a boolean specifying if the data is fresh + or not. + """ + global _FILE_CACHE + + if force_reload and filename in _FILE_CACHE: + del _FILE_CACHE[filename] + + reloaded = False + mtime = os.path.getmtime(filename) + cache_info = _FILE_CACHE.setdefault(filename, {}) + + if not cache_info or mtime > cache_info.get('mtime', 0): + LOG.debug(_("Reloading cached file %s") % filename) + with open(filename) as fap: + cache_info['data'] = fap.read() + cache_info['mtime'] = mtime + reloaded = True + return (reloaded, cache_info['data']) + + +def delete_if_exists(path): + """Delete a file, but ignore file not found error. + + :param path: File to delete + """ + + try: + os.unlink(path) + except OSError as e: + if e.errno == errno.ENOENT: + return + else: + raise + + +@contextlib.contextmanager +def remove_path_on_error(path): + """Protect code that wants to operate on PATH atomically. + Any exception will cause PATH to be removed. + + :param path: File to work with + """ + try: + yield + except Exception: + with excutils.save_and_reraise_exception(): + delete_if_exists(path) + + +def file_open(*args, **kwargs): + """Open file + + see built-in file() documentation for more details + + Note: The reason this is kept in a separate module is to easily + be able to provide a stub module that doesn't alter system + state at all (for unit tests) + """ + return file(*args, **kwargs) diff --git a/cinder/utils.py b/cinder/utils.py index 281dd6586..51f4fb9f1 100644 --- a/cinder/utils.py +++ b/cinder/utils.py @@ -705,18 +705,6 @@ def utf8(value): return value -def delete_if_exists(pathname): - """delete a file, but ignore file not found error""" - - try: - os.unlink(pathname) - except OSError as e: - if e.errno == errno.ENOENT: - return - else: - raise - - def get_from_path(items, path): """Returns a list of items matching the specified path. @@ -925,18 +913,6 @@ def logging_error(message): LOG.exception(message) -@contextlib.contextmanager -def remove_path_on_error(path): - """Protect code that wants to operate on PATH atomically. - Any exception will cause PATH to be removed. - """ - try: - yield - except Exception: - with excutils.save_and_reraise_exception(): - delete_if_exists(path) - - def make_dev_path(dev, partition=None, base='/dev'): """Return a path to a particular device. @@ -994,18 +970,6 @@ def read_cached_file(filename, cache_info, reload_func=None): return cache_info['data'] -def file_open(*args, **kwargs): - """Open file - - see built-in file() documentation for more details - - Note: The reason this is kept in a separate module is to easily - be able to provide a stub module that doesn't alter system - state at all (for unit tests) - """ - return file(*args, **kwargs) - - def hash_file(file_like_object): """Generate a hash for the contents of a file.""" checksum = hashlib.sha1() @@ -1165,21 +1129,6 @@ class UndoManager(object): self._rollback() -def ensure_tree(path): - """Create a directory (and any ancestor directories required) - - :param path: Directory to create - """ - try: - os.makedirs(path) - except OSError as exc: - if exc.errno == errno.EEXIST: - if not os.path.isdir(path): - raise - else: - raise - - def to_bytes(text, default=0): """Try to turn a string into a number of bytes. Looks at the last characters of the text to determine what conversion is needed to diff --git a/cinder/volume/drivers/lvm.py b/cinder/volume/drivers/lvm.py index f9fc56902..2fb33dee3 100644 --- a/cinder/volume/drivers/lvm.py +++ b/cinder/volume/drivers/lvm.py @@ -29,6 +29,7 @@ from oslo.config import cfg from cinder.brick.iscsi import iscsi from cinder import exception from cinder.image import image_utils +from cinder.openstack.common import fileutils from cinder.openstack.common import log as logging from cinder import utils from cinder.volume import driver @@ -289,14 +290,14 @@ class LVMVolumeDriver(driver.VolumeDriver): volume = self.db.volume_get(context, backup['volume_id']) volume_path = self.local_path(volume) with utils.temporary_chown(volume_path): - with utils.file_open(volume_path) as volume_file: + with fileutils.file_open(volume_path) as volume_file: backup_service.backup(backup, volume_file) def restore_backup(self, context, backup, volume, backup_service): """Restore an existing backup to a new or existing volume.""" volume_path = self.local_path(volume) with utils.temporary_chown(volume_path): - with utils.file_open(volume_path, 'wb') as volume_file: + with fileutils.file_open(volume_path, 'wb') as volume_file: backup_service.restore(backup, volume['id'], volume_file) diff --git a/cinder/volume/drivers/rbd.py b/cinder/volume/drivers/rbd.py index 617b90477..024ea4cd7 100644 --- a/cinder/volume/drivers/rbd.py +++ b/cinder/volume/drivers/rbd.py @@ -27,8 +27,8 @@ from oslo.config import cfg from cinder import exception from cinder.image import image_utils +from cinder.openstack.common import fileutils from cinder.openstack.common import log as logging -from cinder import utils from cinder.volume import driver try: @@ -420,7 +420,7 @@ class RBDDriver(driver.VolumeDriver): tmp_dir = self.configuration.volume_tmp_dir or '/tmp' tmp_file = os.path.join(tmp_dir, volume['name'] + '-' + image_meta['id']) - with utils.remove_path_on_error(tmp_file): + with fileutils.remove_path_on_error(tmp_file): args = ['rbd', 'export', '--pool', self.configuration.rbd_pool, volume['name'], tmp_file] -- 2.45.2