]>
git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/volumes/fs/operations/group.py
4 from contextlib
import contextmanager
8 from .snapshot_util
import mksnap
, rmsnap
9 from .template
import GroupTemplate
10 from ..fs_util
import listdir
, get_ancestor_xattr
11 from ..exception
import VolumeException
13 log
= logging
.getLogger(__name__
)
15 class Group(GroupTemplate
):
16 # Reserved subvolume group name which we use in paths for subvolumes
17 # that are not assigned to a group (i.e. created with group=None)
18 NO_GROUP_NAME
= "_nogroup"
20 def __init__(self
, fs
, vol_spec
, groupname
):
21 assert groupname
!= Group
.NO_GROUP_NAME
25 self
.vol_spec
= vol_spec
26 self
.groupname
= groupname
if groupname
else Group
.NO_GROUP_NAME
30 return os
.path
.join(self
.vol_spec
.base_dir
.encode('utf-8'), self
.groupname
.encode('utf-8'))
52 def is_default_group(self
):
53 return self
.groupname
== Group
.NO_GROUP_NAME
55 def list_subvolumes(self
):
57 return listdir(self
.fs
, self
.path
)
58 except VolumeException
as ve
:
59 # listing a default group when it's not yet created
60 if ve
.errno
== -errno
.ENOENT
and self
.is_default_group():
64 def create_snapshot(self
, snapname
):
65 snappath
= os
.path
.join(self
.path
,
66 self
.vol_spec
.snapshot_dir_prefix
.encode('utf-8'),
67 snapname
.encode('utf-8'))
68 mksnap(self
.fs
, snappath
)
70 def remove_snapshot(self
, snapname
):
71 snappath
= os
.path
.join(self
.path
,
72 self
.vol_spec
.snapshot_dir_prefix
.encode('utf-8'),
73 snapname
.encode('utf-8'))
74 rmsnap(self
.fs
, snappath
)
76 def list_snapshots(self
):
78 dirpath
= os
.path
.join(self
.path
,
79 self
.vol_spec
.snapshot_dir_prefix
.encode('utf-8'))
80 return listdir(self
.fs
, dirpath
)
81 except VolumeException
as ve
:
82 if ve
.errno
== -errno
.ENOENT
:
86 def create_group(fs
, vol_spec
, groupname
, pool
, mode
, uid
, gid
):
88 create a subvolume group.
90 :param fs: ceph filesystem handle
91 :param vol_spec: volume specification
92 :param groupname: subvolume group name
93 :param pool: the RADOS pool where the data objects of the subvolumes will be stored
94 :param mode: the user permissions
95 :param uid: the user identifier
96 :param gid: the group identifier
99 group
= Group(fs
, vol_spec
, groupname
)
101 fs
.mkdirs(path
, mode
)
104 pool
= get_ancestor_xattr(fs
, path
, "ceph.dir.layout.pool")
106 fs
.setxattr(path
, 'ceph.dir.layout.pool', pool
.encode('utf-8'), 0)
107 except cephfs
.InvalidValue
:
108 raise VolumeException(-errno
.EINVAL
,
109 "Invalid pool layout '{0}'. It must be a valid data pool".format(pool
))
118 raise VolumeException(-errno
.EINVAL
, "invalid UID")
127 raise VolumeException(-errno
.EINVAL
, "invalid GID")
128 fs
.chown(path
, uid
, gid
)
129 except (cephfs
.Error
, VolumeException
) as e
:
131 # cleanup group path on best effort basis
132 log
.debug("cleaning up subvolume group path: {0}".format(path
))
134 except cephfs
.Error
as ce
:
135 log
.debug("failed to clean up subvolume group {0} with path: {1} ({2})".format(groupname
, path
, ce
))
136 if isinstance(e
, cephfs
.Error
):
137 e
= VolumeException(-e
.args
[0], e
.args
[1])
140 def remove_group(fs
, vol_spec
, groupname
):
142 remove a subvolume group.
144 :param fs: ceph filesystem handle
145 :param vol_spec: volume specification
146 :param groupname: subvolume group name
149 group
= Group(fs
, vol_spec
, groupname
)
152 except cephfs
.Error
as e
:
153 if e
.args
[0] == errno
.ENOENT
:
154 raise VolumeException(-errno
.ENOENT
, "subvolume group '{0}' does not exist".format(groupname
))
155 raise VolumeException(-e
.args
[0], e
.args
[1])
158 def open_group(fs
, vol_spec
, groupname
):
160 open a subvolume group. This API is to be used as a context manager.
162 :param fs: ceph filesystem handle
163 :param vol_spec: volume specification
164 :param groupname: subvolume group name
165 :return: yields a group object (subclass of GroupTemplate)
167 group
= Group(fs
, vol_spec
, groupname
)
169 st
= fs
.stat(group
.path
)
170 group
.uid
= int(st
.st_uid
)
171 group
.gid
= int(st
.st_gid
)
172 except cephfs
.Error
as e
:
173 if e
.args
[0] == errno
.ENOENT
:
174 if not group
.is_default_group():
175 raise VolumeException(-errno
.ENOENT
, "subvolume group '{0}' does not exist".format(groupname
))
177 raise VolumeException(-e
.args
[0], e
.args
[1])