summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhongyue Luo <zhongyue.nah@intel.com>2013-06-10 14:43:41 +0800
committerZhongyue Luo <zhongyue.nah@intel.com>2013-06-11 13:28:29 +0900
commitab1977af316eef5375c7aaefdf364548b4fb5289 (patch)
treeabdded324a0220e9b17b78e5dc5c18c94b1f2b2d
parentf85e4ec079283f4217415b4fd6a37ced189bc49a (diff)
downloadnova-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.py75
-rw-r--r--nova/tests/test_configdrive2.py5
-rw-r--r--nova/tests/virt/libvirt/test_libvirt.py2
-rw-r--r--nova/utils.py37
-rw-r--r--nova/virt/configdrive.py2
-rwxr-xr-xnova/virt/images.py7
-rwxr-xr-xnova/virt/libvirt/driver.py2
-rwxr-xr-xnova/virt/libvirt/imagebackend.py8
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):