]>
git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/volumes/fs/operations/group.py
aac81f299346afcb706577adca2a4d8ab5375908
4 from contextlib
import contextmanager
8 from .snapshot_util
import mksnap
, rmsnap
9 from .pin_util
import pin
10 from .template
import GroupTemplate
11 from ..fs_util
import listdir
, get_ancestor_xattr
12 from ..exception
import VolumeException
14 log
= logging
.getLogger(__name__
)
16 class Group(GroupTemplate
):
17 # Reserved subvolume group name which we use in paths for subvolumes
18 # that are not assigned to a group (i.e. created with group=None)
19 NO_GROUP_NAME
= "_nogroup"
21 def __init__(self
, fs
, vol_spec
, groupname
):
22 assert groupname
!= Group
.NO_GROUP_NAME
26 self
.vol_spec
= vol_spec
27 self
.groupname
= groupname
if groupname
else Group
.NO_GROUP_NAME
31 return os
.path
.join(self
.vol_spec
.base_dir
.encode('utf-8'), self
.groupname
.encode('utf-8'))
53 def is_default_group(self
):
54 return self
.groupname
== Group
.NO_GROUP_NAME
56 def list_subvolumes(self
):
58 return listdir(self
.fs
, self
.path
)
59 except VolumeException
as ve
:
60 # listing a default group when it's not yet created
61 if ve
.errno
== -errno
.ENOENT
and self
.is_default_group():
65 def pin(self
, pin_type
, pin_setting
):
66 return pin(self
.fs
, self
.path
, pin_type
, pin_setting
)
68 def create_snapshot(self
, snapname
):
69 snappath
= os
.path
.join(self
.path
,
70 self
.vol_spec
.snapshot_dir_prefix
.encode('utf-8'),
71 snapname
.encode('utf-8'))
72 mksnap(self
.fs
, snappath
)
74 def remove_snapshot(self
, snapname
):
75 snappath
= os
.path
.join(self
.path
,
76 self
.vol_spec
.snapshot_dir_prefix
.encode('utf-8'),
77 snapname
.encode('utf-8'))
78 rmsnap(self
.fs
, snappath
)
80 def list_snapshots(self
):
82 dirpath
= os
.path
.join(self
.path
,
83 self
.vol_spec
.snapshot_dir_prefix
.encode('utf-8'))
84 return listdir(self
.fs
, dirpath
)
85 except VolumeException
as ve
:
86 if ve
.errno
== -errno
.ENOENT
:
90 def create_group(fs
, vol_spec
, groupname
, pool
, mode
, uid
, gid
):
92 create a subvolume group.
94 :param fs: ceph filesystem handle
95 :param vol_spec: volume specification
96 :param groupname: subvolume group name
97 :param pool: the RADOS pool where the data objects of the subvolumes will be stored
98 :param mode: the user permissions
99 :param uid: the user identifier
100 :param gid: the group identifier
103 group
= Group(fs
, vol_spec
, groupname
)
105 fs
.mkdirs(path
, mode
)
108 pool
= get_ancestor_xattr(fs
, path
, "ceph.dir.layout.pool")
110 fs
.setxattr(path
, 'ceph.dir.layout.pool', pool
.encode('utf-8'), 0)
111 except cephfs
.InvalidValue
:
112 raise VolumeException(-errno
.EINVAL
,
113 "Invalid pool layout '{0}'. It must be a valid data pool".format(pool
))
122 raise VolumeException(-errno
.EINVAL
, "invalid UID")
131 raise VolumeException(-errno
.EINVAL
, "invalid GID")
132 fs
.chown(path
, uid
, gid
)
133 except (cephfs
.Error
, VolumeException
) as e
:
135 # cleanup group path on best effort basis
136 log
.debug("cleaning up subvolume group path: {0}".format(path
))
138 except cephfs
.Error
as ce
:
139 log
.debug("failed to clean up subvolume group {0} with path: {1} ({2})".format(groupname
, path
, ce
))
140 if isinstance(e
, cephfs
.Error
):
141 e
= VolumeException(-e
.args
[0], e
.args
[1])
144 def remove_group(fs
, vol_spec
, groupname
):
146 remove a subvolume group.
148 :param fs: ceph filesystem handle
149 :param vol_spec: volume specification
150 :param groupname: subvolume group name
153 group
= Group(fs
, vol_spec
, groupname
)
156 except cephfs
.Error
as e
:
157 if e
.args
[0] == errno
.ENOENT
:
158 raise VolumeException(-errno
.ENOENT
, "subvolume group '{0}' does not exist".format(groupname
))
159 raise VolumeException(-e
.args
[0], e
.args
[1])
162 def open_group(fs
, vol_spec
, groupname
):
164 open a subvolume group. This API is to be used as a context manager.
166 :param fs: ceph filesystem handle
167 :param vol_spec: volume specification
168 :param groupname: subvolume group name
169 :return: yields a group object (subclass of GroupTemplate)
171 group
= Group(fs
, vol_spec
, groupname
)
173 st
= fs
.stat(group
.path
)
174 group
.uid
= int(st
.st_uid
)
175 group
.gid
= int(st
.st_gid
)
176 except cephfs
.Error
as e
:
177 if e
.args
[0] == errno
.ENOENT
:
178 if not group
.is_default_group():
179 raise VolumeException(-errno
.ENOENT
, "subvolume group '{0}' does not exist".format(groupname
))
181 raise VolumeException(-e
.args
[0], e
.args
[1])
185 def open_group_unique(fs
, vol_spec
, groupname
, c_group
, c_groupname
):
186 if groupname
== c_groupname
:
189 with
open_group(fs
, vol_spec
, groupname
) as group
: