diff options
| author | Zhongyue Luo <zhongyue.nah@intel.com> | 2013-06-10 14:43:41 +0800 |
|---|---|---|
| committer | Zhongyue Luo <zhongyue.nah@intel.com> | 2013-06-11 13:28:29 +0900 |
| commit | ab1977af316eef5375c7aaefdf364548b4fb5289 (patch) | |
| tree | abdded324a0220e9b17b78e5dc5c18c94b1f2b2d | |
| parent | f85e4ec079283f4217415b4fd6a37ced189bc49a (diff) | |
| download | nova-ab1977af316eef5375c7aaefdf364548b4fb5289.tar.gz nova-ab1977af316eef5375c7aaefdf364548b4fb5289.tar.xz nova-ab1977af316eef5375c7aaefdf364548b4fb5289.zip | |
Replace functions in utils with oslo.fileutils
The following functions have moved to oslo.
remove_path_on_error
file_open
delete_if_exists
Replaced/removed overlapping functions with the ones in fileutils
Change-Id: I41a19d76a777b6f899843bb0cc0582630accbd5c
| -rw-r--r-- | nova/openstack/common/fileutils.py | 75 | ||||
| -rw-r--r-- | nova/tests/test_configdrive2.py | 5 | ||||
| -rw-r--r-- | nova/tests/virt/libvirt/test_libvirt.py | 2 | ||||
| -rw-r--r-- | nova/utils.py | 37 | ||||
| -rw-r--r-- | nova/virt/configdrive.py | 2 | ||||
| -rwxr-xr-x | nova/virt/images.py | 7 | ||||
| -rwxr-xr-x | nova/virt/libvirt/driver.py | 2 | ||||
| -rwxr-xr-x | nova/virt/libvirt/imagebackend.py | 8 |
8 files changed, 89 insertions, 49 deletions
diff --git a/nova/openstack/common/fileutils.py b/nova/openstack/common/fileutils.py index b988ad03d..53e07a2a5 100644 --- a/nova/openstack/common/fileutils.py +++ b/nova/openstack/common/fileutils.py @@ -16,9 +16,18 @@ # under the License. +import contextlib import errno import os +from nova.openstack.common import excutils +from nova.openstack.common.gettextutils import _ +from nova.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/nova/tests/test_configdrive2.py b/nova/tests/test_configdrive2.py index a71a01f8f..490edc4ed 100644 --- a/nova/tests/test_configdrive2.py +++ b/nova/tests/test_configdrive2.py @@ -22,6 +22,7 @@ import tempfile from nova import test +from nova.openstack.common import fileutils from nova import utils from nova.virt import configdrive @@ -53,7 +54,7 @@ class ConfigDriveTestCase(test.TestCase): finally: if imagefile: - utils.delete_if_exists(imagefile) + fileutils.delete_if_exists(imagefile) def test_create_configdrive_vfat(self): imagefile = None @@ -87,4 +88,4 @@ class ConfigDriveTestCase(test.TestCase): finally: if imagefile: - utils.delete_if_exists(imagefile) + fileutils.delete_if_exists(imagefile) diff --git a/nova/tests/virt/libvirt/test_libvirt.py b/nova/tests/virt/libvirt/test_libvirt.py index 2f5f9c857..b6f2a3d8a 100644 --- a/nova/tests/virt/libvirt/test_libvirt.py +++ b/nova/tests/virt/libvirt/test_libvirt.py @@ -4745,7 +4745,7 @@ disk size: 4.4M''', '')) self.stubs.Set(os, 'unlink', fake_unlink) self.stubs.Set(images, 'fetch', lambda *_: None) self.stubs.Set(images, 'qemu_img_info', fake_qemu_img_info) - self.stubs.Set(utils, 'delete_if_exists', fake_rm_on_errror) + self.stubs.Set(fileutils, 'delete_if_exists', fake_rm_on_errror) context = 'opaque context' image_id = '4' diff --git a/nova/utils.py b/nova/utils.py index 9067488d5..41d18b3cb 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -21,7 +21,6 @@ import contextlib import datetime -import errno import functools import hashlib import inspect @@ -439,18 +438,6 @@ def to_bytes(text, default=0): return default -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. @@ -733,18 +720,6 @@ def timefunc(func): return inner -@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. @@ -803,18 +778,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() diff --git a/nova/virt/configdrive.py b/nova/virt/configdrive.py index 57e5155c8..173dd457b 100644 --- a/nova/virt/configdrive.py +++ b/nova/virt/configdrive.py @@ -169,7 +169,7 @@ class ConfigDriveBuilder(object): def cleanup(self): if self.imagefile: - utils.delete_if_exists(self.imagefile) + fileutils.delete_if_exists(self.imagefile) try: shutil.rmtree(self.tempdir) diff --git a/nova/virt/images.py b/nova/virt/images.py index b40f566a6..08d275bc6 100755 --- a/nova/virt/images.py +++ b/nova/virt/images.py @@ -28,6 +28,7 @@ from oslo.config import cfg from nova import exception from nova.image import glance +from nova.openstack.common import fileutils from nova.openstack.common import log as logging from nova import utils @@ -197,7 +198,7 @@ def fetch(context, image_href, path, _user_id, _project_id): # checked before we got here. (image_service, image_id) = glance.get_remote_image_service(context, image_href) - 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) @@ -206,7 +207,7 @@ def fetch_to_raw(context, image_href, path, user_id, project_id): path_tmp = "%s.part" % path fetch(context, image_href, path_tmp, user_id, project_id) - with utils.remove_path_on_error(path_tmp): + with fileutils.remove_path_on_error(path_tmp): data = qemu_img_info(path_tmp) fmt = data.file_format @@ -223,7 +224,7 @@ def fetch_to_raw(context, image_href, path, user_id, project_id): if fmt != "raw" and CONF.force_raw_images: staged = "%s.converted" % path LOG.debug("%s was %s, converting to raw" % (image_href, fmt)) - with utils.remove_path_on_error(staged): + with fileutils.remove_path_on_error(staged): convert_image(path_tmp, staged, 'raw') os.unlink(path_tmp) diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index c0cec7a43..135791f3d 100755 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -2932,7 +2932,7 @@ class LibvirtDriver(driver.ComputeDriver): return os.path.exists(data['filename']) def check_instance_shared_storage_cleanup(self, ctxt, data): - utils.delete_if_exists(data["filename"]) + fileutils.delete_if_exists(data["filename"]) def check_can_live_migrate_destination(self, ctxt, instance_ref, src_compute_info, dst_compute_info, diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py index 844d9dfde..c564d2d24 100755 --- a/nova/virt/libvirt/imagebackend.py +++ b/nova/virt/libvirt/imagebackend.py @@ -166,7 +166,7 @@ class Image(object): if can_fallocate is None: _out, err = utils.trycmd('fallocate', '-n', '-l', '1', self.path + '.fallocate_test') - utils.delete_if_exists(self.path + '.fallocate_test') + fileutils.delete_if_exists(self.path + '.fallocate_test') can_fallocate = not err self.__class__.can_fallocate = can_fallocate if not can_fallocate: @@ -215,7 +215,7 @@ class Raw(Image): else: prepare_template(target=base, *args, **kwargs) if not os.path.exists(self.path): - with utils.remove_path_on_error(self.path): + with fileutils.remove_path_on_error(self.path): copy_raw_image(base, self.path, size) self.correct_format() @@ -273,7 +273,7 @@ class Qcow2(Image): # Create the legacy backing file if necessary. if legacy_backing_size: if not os.path.exists(legacy_base): - with utils.remove_path_on_error(legacy_base): + with fileutils.remove_path_on_error(legacy_base): libvirt_utils.copy_image(base, legacy_base) disk.extend(legacy_base, legacy_backing_size) @@ -285,7 +285,7 @@ class Qcow2(Image): (base, size)) raise exception.InstanceTypeDiskTooSmall() if not os.path.exists(self.path): - with utils.remove_path_on_error(self.path): + with fileutils.remove_path_on_error(self.path): copy_qcow2_image(base, self.path, size) def snapshot_create(self): |
