]> git.proxmox.com Git - ceph.git/blame - ceph/src/pybind/mgr/volumes/fs/operations/versions/__init__.py
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / pybind / mgr / volumes / fs / operations / versions / __init__.py
CommitLineData
92f5a8d4
TL
1import errno
2import logging
3import importlib
4
5import cephfs
6
7from .subvolume_base import SubvolumeBase
8from ..op_sm import OpSm
9from ...exception import VolumeException, MetadataMgrException
10
11log = logging.getLogger(__name__)
12
13class SubvolumeLoader(object):
14 INVALID_VERSION = -1
15
16 SUPPORTED_MODULES = ['subvolume_v1.SubvolumeV1']
17
18 def __init__(self):
19 self.max_version = SubvolumeLoader.INVALID_VERSION
20 self.versions = {}
21
22 def _load_module(self, mod_cls):
23 mod_name, cls_name = mod_cls.split('.')
24 mod = importlib.import_module('.versions.{0}'.format(mod_name), package='volumes.fs.operations')
25 return getattr(mod, cls_name)
26
27 def _load_supported_versions(self):
28 for mod_cls in SubvolumeLoader.SUPPORTED_MODULES:
29 cls = self._load_module(mod_cls)
30 log.info("loaded v{0} subvolume".format(cls.version()))
31 if self.max_version is not None or cls.version() > self.max_version:
32 self.max_version = cls.version()
33 self.versions[cls.version()] = cls
34 if self.max_version == SubvolumeLoader.INVALID_VERSION:
35 raise VolumeException("no subvolume version available")
36 log.info("max subvolume version is v{0}".format(self.max_version))
37
38 def _get_subvolume_version(self, version):
39 try:
40 return self.versions[version]
41 except KeyError:
42 raise VolumeException(-errno.EINVAL, "subvolume class v{0} does not exist".format(version))
43
44 def get_subvolume_object_max(self, fs, vol_spec, group, subvolname):
45 return self._get_subvolume_version(self.max_version)(fs, vol_spec, group, subvolname)
46
47 def upgrade_legacy_subvolume(self, fs, subvolume):
48 assert subvolume.legacy_mode
49 try:
50 fs.mkdirs(subvolume.legacy_dir, 0o700)
51 except cephfs.Error as e:
52 raise VolumeException(-e.args[0], "error accessing subvolume")
53 subvolume_type = SubvolumeBase.SUBVOLUME_TYPE_NORMAL
54 try:
55 initial_state = OpSm.get_init_state(subvolume_type)
56 except OpSmException as oe:
57 raise VolumeException(-errno.EINVAL, "subvolume creation failed: internal error")
58 qpath = subvolume.base_path.decode('utf-8')
59 subvolume.init_config(self.max_version, subvolume_type, qpath, initial_state)
60
61 def get_subvolume_object(self, fs, vol_spec, group, subvolname, upgrade=True):
62 subvolume = SubvolumeBase(fs, vol_spec, group, subvolname)
63 try:
64 subvolume.discover()
65 version = int(subvolume.metadata_mgr.get_global_option('version'))
66 return self._get_subvolume_version(version)(fs, vol_spec, group, subvolname, legacy=subvolume.legacy_mode)
67 except MetadataMgrException as me:
68 if me.errno == -errno.ENOENT and upgrade:
69 self.upgrade_legacy_subvolume(fs, subvolume)
70 subvolume = None
71 return self.get_subvolume_object(fs, vol_spec, group, subvolname, upgrade=False)
72 else:
73 # log the actual error and generalize error string returned to user
74 log.error("error accessing subvolume metadata for '{0}' ({1})".format(subvolname, me))
75 raise VolumeException(-errno.EINVAL, "error accessing subvolume metadata")
76
77loaded_subvolumes = SubvolumeLoader()
78loaded_subvolumes._load_supported_versions()