subvolume.remove()
@contextmanager
-def open_subvol(fs, vol_spec, group, subvolname):
+def open_subvol(fs, vol_spec, group, subvolname, need_complete=True, expected_types=[]):
"""
open a subvolume. This API is to be used as a context manager.
:param vol_spec: volume specification
:param group: group object for the subvolume
:param subvolname: subvolume name
+ :param need_complete: check if the subvolume is usable (since cloned subvolumes can
+ be in transient state). defaults to True.
+ :param expected_types: check if the subvolume is one the provided types. defaults to
+ all.
:return: yields a subvolume object (subclass of SubvolumeTemplate)
"""
subvolume = loaded_subvolumes.get_subvolume_object(fs, vol_spec, group, subvolname)
- subvolume.open()
+ subvolume.open(need_complete, expected_types)
yield subvolume
def version():
return SubvolumeTemplate.VERSION
- def open(self):
+ def open(self, need_complete=True, expected_types=[]):
raise VolumeException(-errno.ENOTSUP, "operation not supported.")
def create(self, size, isolate_nspace, pool, mode, uid, gid):
import cephfs
+from .metadata_manager import MetadataManager
from .subvolume_base import SubvolumeBase
from ..op_sm import OpSm
from ..template import SubvolumeTemplate
e = VolumeException(-e.args[0], e.args[1])
raise e
- def open(self):
+ def open(self, need_complete=True, expected_types=[]):
try:
self.metadata_mgr.refresh()
subvol_path = self.path
log.debug("refreshed metadata, checking subvolume path '{0}'".format(subvol_path))
st = self.fs.stat(subvol_path)
+ etype = self.metadata_mgr.get_global_option(MetadataManager.GLOBAL_META_KEY_TYPE)
+ if len(expected_types) and not etype in expected_types:
+ raise VolumeException(-errno.ENOTSUP, "subvolume '{0}' is not {1}".format(
+ self.subvolname, "a {0}".format(expected_types[0]) if len(expected_types) == 1 else \
+ "one of types ({0})".format(",".join(expected_types))))
+ if need_complete:
+ estate = self.metadata_mgr.get_global_option(MetadataManager.GLOBAL_META_KEY_STATE)
+ if not OpSm.is_final_state(estate):
+ raise VolumeException(-errno.EAGAIN, "subvolume '{0}' is not ready for use".format(self.subvolname))
self.uid = int(st.st_uid)
self.gid = int(st.st_gid)
self.mode = int(st.st_mode & ~stat.S_IFMT(st.st_mode))