]>
git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/volumes/fs/operations/group.py
69e3959d7aa3d2ab684967854c9613382fe4d933
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
, listsnaps
, get_ancestor_xattr
, create_base_dir
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 listsnaps(self
.fs
, self
.vol_spec
, dirpath
, filter_inherited_snaps
=True)
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 vol_spec_base_dir
= group
.vol_spec
.base_dir
.encode('utf-8')
107 # create vol_spec base directory with default mode(0o755) if it doesn't exist
108 create_base_dir(fs
, vol_spec_base_dir
, vol_spec
.DEFAULT_MODE
)
112 pool
= get_ancestor_xattr(fs
, path
, "ceph.dir.layout.pool")
114 fs
.setxattr(path
, 'ceph.dir.layout.pool', pool
.encode('utf-8'), 0)
115 except cephfs
.InvalidValue
:
116 raise VolumeException(-errno
.EINVAL
,
117 "Invalid pool layout '{0}'. It must be a valid data pool".format(pool
))
126 raise VolumeException(-errno
.EINVAL
, "invalid UID")
135 raise VolumeException(-errno
.EINVAL
, "invalid GID")
136 fs
.chown(path
, uid
, gid
)
137 except (cephfs
.Error
, VolumeException
) as e
:
139 # cleanup group path on best effort basis
140 log
.debug("cleaning up subvolume group path: {0}".format(path
))
142 except cephfs
.Error
as ce
:
143 log
.debug("failed to clean up subvolume group {0} with path: {1} ({2})".format(groupname
, path
, ce
))
144 if isinstance(e
, cephfs
.Error
):
145 e
= VolumeException(-e
.args
[0], e
.args
[1])
148 def remove_group(fs
, vol_spec
, groupname
):
150 remove a subvolume group.
152 :param fs: ceph filesystem handle
153 :param vol_spec: volume specification
154 :param groupname: subvolume group name
157 group
= Group(fs
, vol_spec
, groupname
)
160 except cephfs
.Error
as e
:
161 if e
.args
[0] == errno
.ENOENT
:
162 raise VolumeException(-errno
.ENOENT
, "subvolume group '{0}' does not exist".format(groupname
))
163 raise VolumeException(-e
.args
[0], e
.args
[1])
166 def open_group(fs
, vol_spec
, groupname
):
168 open a subvolume group. This API is to be used as a context manager.
170 :param fs: ceph filesystem handle
171 :param vol_spec: volume specification
172 :param groupname: subvolume group name
173 :return: yields a group object (subclass of GroupTemplate)
175 group
= Group(fs
, vol_spec
, groupname
)
177 st
= fs
.stat(group
.path
)
178 group
.uid
= int(st
.st_uid
)
179 group
.gid
= int(st
.st_gid
)
180 except cephfs
.Error
as e
:
181 if e
.args
[0] == errno
.ENOENT
:
182 if not group
.is_default_group():
183 raise VolumeException(-errno
.ENOENT
, "subvolume group '{0}' does not exist".format(groupname
))
185 raise VolumeException(-e
.args
[0], e
.args
[1])
189 def open_group_unique(fs
, vol_spec
, groupname
, c_group
, c_groupname
):
190 if groupname
== c_groupname
:
193 with
open_group(fs
, vol_spec
, groupname
) as group
: