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
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
# 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:
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
# 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)
# 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)
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
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'])
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)
# 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)
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)
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.
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.
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()
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
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
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)
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:
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]