]> git.proxmox.com Git - ceph.git/blame - ceph/src/pybind/mgr/volumes/module.py
import 14.2.4 nautilus point release
[ceph.git] / ceph / src / pybind / mgr / volumes / module.py
CommitLineData
11fdf7f2
TL
1from threading import Event
2import errno
3import json
4try:
5 import queue as Queue
6except ImportError:
7 import Queue
8
9from mgr_module import MgrModule
10import orchestrator
11
81eedcae 12from .fs.volume import VolumeClient
11fdf7f2
TL
13
14class PurgeJob(object):
15 def __init__(self, volume_fscid, subvolume_path):
16 """
17 Purge tasks work in terms of FSCIDs, so that if we process
18 a task later when a volume was deleted and recreated with
19 the same name, we can correctly drop the task that was
20 operating on the original volume.
21 """
22 self.fscid = volume_fscid
23 self.subvolume_path = subvolume_path
24
11fdf7f2
TL
25class Module(orchestrator.OrchestratorClientMixin, MgrModule):
26 COMMANDS = [
27 {
28 'cmd': 'fs volume ls',
29 'desc': "List volumes",
30 'perm': 'r'
31 },
32 {
33 'cmd': 'fs volume create '
34 'name=name,type=CephString '
35 'name=size,type=CephString,req=false ',
36 'desc': "Create a CephFS volume",
37 'perm': 'rw'
38 },
39 {
40 'cmd': 'fs volume rm '
41 'name=vol_name,type=CephString',
42 'desc': "Delete a CephFS volume",
43 'perm': 'rw'
44 },
81eedcae
TL
45 {
46 'cmd': 'fs subvolumegroup create '
47 'name=vol_name,type=CephString '
48 'name=group_name,type=CephString '
49 'name=pool_layout,type=CephString,req=false '
50 'name=mode,type=CephString,req=false ',
51 'desc': "Create a CephFS subvolume group in a volume, and optionally, "
52 "with a specific data pool layout, and a specific numeric mode",
53 'perm': 'rw'
54 },
55 {
56 'cmd': 'fs subvolumegroup rm '
57 'name=vol_name,type=CephString '
58 'name=group_name,type=CephString '
59 'name=force,type=CephBool,req=false ',
60 'desc': "Delete a CephFS subvolume group in a volume",
61 'perm': 'rw'
62 },
11fdf7f2
TL
63 {
64 'cmd': 'fs subvolume create '
65 'name=vol_name,type=CephString '
66 'name=sub_name,type=CephString '
81eedcae
TL
67 'name=size,type=CephInt,req=false '
68 'name=group_name,type=CephString,req=false '
69 'name=pool_layout,type=CephString,req=false '
70 'name=mode,type=CephString,req=false ',
71 'desc': "Create a CephFS subvolume in a volume, and optionally, "
72 "with a specific size (in bytes), a specific data pool layout, "
73 "a specific mode, and in a specific subvolume group",
11fdf7f2
TL
74 'perm': 'rw'
75 },
76 {
77 'cmd': 'fs subvolume rm '
78 'name=vol_name,type=CephString '
81eedcae
TL
79 'name=sub_name,type=CephString '
80 'name=group_name,type=CephString,req=false '
81 'name=force,type=CephBool,req=false ',
82 'desc': "Delete a CephFS subvolume in a volume, and optionally, "
83 "in a specific subvolume group",
84 'perm': 'rw'
85 },
494da23a
TL
86 {
87 'cmd': 'fs subvolumegroup getpath '
88 'name=vol_name,type=CephString '
89 'name=group_name,type=CephString ',
90 'desc': "Get the mountpath of a CephFS subvolume group in a volume",
91 'perm': 'r'
92 },
81eedcae
TL
93 {
94 'cmd': 'fs subvolume getpath '
95 'name=vol_name,type=CephString '
96 'name=sub_name,type=CephString '
97 'name=group_name,type=CephString,req=false ',
98 'desc': "Get the mountpath of a CephFS subvolume in a volume, "
99 "and optionally, in a specific subvolume group",
100 'perm': 'rw'
101 },
102 {
103 'cmd': 'fs subvolumegroup snapshot create '
104 'name=vol_name,type=CephString '
105 'name=group_name,type=CephString '
106 'name=snap_name,type=CephString ',
107 'desc': "Create a snapshot of a CephFS subvolume group in a volume",
108 'perm': 'rw'
109 },
110 {
111 'cmd': 'fs subvolumegroup snapshot rm '
112 'name=vol_name,type=CephString '
113 'name=group_name,type=CephString '
114 'name=snap_name,type=CephString '
115 'name=force,type=CephBool,req=false ',
116 'desc': "Delete a snapshot of a CephFS subvolume group in a volume",
117 'perm': 'rw'
118 },
119 {
120 'cmd': 'fs subvolume snapshot create '
121 'name=vol_name,type=CephString '
122 'name=sub_name,type=CephString '
123 'name=snap_name,type=CephString '
124 'name=group_name,type=CephString,req=false ',
125 'desc': "Create a snapshot of a CephFS subvolume in a volume, "
126 "and optionally, in a specific subvolume group",
127 'perm': 'rw'
128 },
129 {
130 'cmd': 'fs subvolume snapshot rm '
131 'name=vol_name,type=CephString '
132 'name=sub_name,type=CephString '
133 'name=snap_name,type=CephString '
134 'name=group_name,type=CephString,req=false '
135 'name=force,type=CephBool,req=false ',
136 'desc': "Delete a snapshot of a CephFS subvolume in a volume, "
137 "and optionally, in a specific subvolume group",
11fdf7f2
TL
138 'perm': 'rw'
139 },
140
141 # volume ls [recursive]
142 # subvolume ls <volume>
143 # volume authorize/deauthorize
144 # subvolume authorize/deauthorize
145
146 # volume describe (free space, etc)
147 # volume auth list (vc.get_authorized_ids)
148
149 # snapshots?
150
151 # FIXME: we're doing CephFSVolumeClient.recover on every
152 # path where we instantiate and connect a client. Perhaps
153 # keep clients alive longer, or just pass a "don't recover"
154 # flag in if it's the >1st time we connected a particular
155 # volume in the lifetime of this module instance.
156 ]
157
158 def __init__(self, *args, **kwargs):
159 super(Module, self).__init__(*args, **kwargs)
160 self._initialized = Event()
81eedcae 161 self.vc = VolumeClient(self)
11fdf7f2
TL
162
163 self._background_jobs = Queue.Queue()
164
165 def serve(self):
166 # TODO: discover any subvolumes pending purge, and enqueue
167 # them in background_jobs at startup
168
169 # TODO: consume background_jobs
170 # skip purge jobs if their fscid no longer exists
171
172 # TODO: on volume delete, cancel out any background jobs that
173 # affect subvolumes within that volume.
174
175 # ... any background init needed? Can get rid of this
176 # and _initialized if not
177 self._initialized.set()
178
179 def handle_command(self, inbuf, cmd):
180 self._initialized.wait()
181
182 handler_name = "_cmd_" + cmd['prefix'].replace(" ", "_")
183 try:
184 handler = getattr(self, handler_name)
185 except AttributeError:
186 return -errno.EINVAL, "", "Unknown command"
187
188 return handler(inbuf, cmd)
189
11fdf7f2 190 def _cmd_fs_volume_create(self, inbuf, cmd):
11fdf7f2
TL
191 # TODO: validate name against any rules for pool/fs names
192 # (...are there any?)
81eedcae 193 vol_id = cmd['name']
11fdf7f2
TL
194 size = cmd.get('size', None)
195
81eedcae 196 return self.vc.create_volume(vol_id, size)
11fdf7f2 197
81eedcae 198 def _cmd_fs_volume_rm(self, inbuf, cmd):
11fdf7f2 199 vol_name = cmd['vol_name']
81eedcae 200 return self.vc.delete_volume(vol_name)
11fdf7f2 201
81eedcae
TL
202 def _cmd_fs_volume_ls(self, inbuf, cmd):
203 return self.vc.list_volumes()
11fdf7f2 204
81eedcae
TL
205 def _cmd_fs_subvolumegroup_create(self, inbuf, cmd):
206 """
207 :return: a 3-tuple of return code(int), empty string(str), error message (str)
208 """
494da23a
TL
209 return self.vc.create_subvolume_group(
210 None, vol_name=cmd['vol_name'], group_name=cmd['group_name'],
211 pool_layout=cmd.get('pool_layout', None), mode=cmd.get('mode', '755'))
11fdf7f2 212
81eedcae
TL
213 def _cmd_fs_subvolumegroup_rm(self, inbuf, cmd):
214 """
215 :return: a 3-tuple of return code(int), empty string(str), error message (str)
216 """
494da23a
TL
217 return self.vc.remove_subvolume_group(None, vol_name=cmd['vol_name'],
218 group_name=cmd['group_name'],
219 force=cmd.get('force', False))
11fdf7f2 220
81eedcae
TL
221 def _cmd_fs_subvolume_create(self, inbuf, cmd):
222 """
223 :return: a 3-tuple of return code(int), empty string(str), error message (str)
224 """
494da23a
TL
225 return self.vc.create_subvolume(None, vol_name=cmd['vol_name'],
226 sub_name=cmd['sub_name'],
227 group_name=cmd.get('group_name', None),
228 size=cmd.get('size', None),
229 pool_layout=cmd.get('pool_layout', None),
230 mode=cmd.get('mode', '755'))
11fdf7f2
TL
231
232 def _cmd_fs_subvolume_rm(self, inbuf, cmd):
81eedcae
TL
233 """
234 :return: a 3-tuple of return code(int), empty string(str), error message (str)
235 """
494da23a
TL
236 return self.vc.remove_subvolume(None, vol_name=cmd['vol_name'],
237 sub_name=cmd['sub_name'],
238 group_name=cmd.get('group_name', None),
239 force=cmd.get('force', False))
11fdf7f2 240
494da23a
TL
241 def _cmd_fs_subvolumegroup_getpath(self, inbuf, cmd):
242 return self.vc.getpath_subvolume_group(
243 None, vol_name=cmd['vol_name'], group_name=cmd['group_name'])
11fdf7f2 244
81eedcae 245 def _cmd_fs_subvolume_getpath(self, inbuf, cmd):
494da23a
TL
246 return self.vc.subvolume_getpath(None, vol_name=cmd['vol_name'],
247 sub_name=cmd['sub_name'],
248 group_name=cmd.get('group_name', None))
11fdf7f2 249
81eedcae 250 def _cmd_fs_subvolumegroup_snapshot_create(self, inbuf, cmd):
494da23a
TL
251 return self.vc.create_subvolume_group_snapshot(None, vol_name=cmd['vol_name'],
252 group_name=cmd['group_name'],
253 snap_name=cmd['snap_name'])
11fdf7f2 254
81eedcae 255 def _cmd_fs_subvolumegroup_snapshot_rm(self, inbuf, cmd):
494da23a
TL
256 return self.vc.remove_subvolume_group_snapshot(None, vol_name=cmd['vol_name'],
257 group_name=cmd['group_name'],
258 snap_name=cmd['snap_name'],
259 force=cmd.get('force', False))
11fdf7f2 260
81eedcae 261 def _cmd_fs_subvolume_snapshot_create(self, inbuf, cmd):
494da23a
TL
262 return self.vc.create_subvolume_snapshot(None, vol_name=cmd['vol_name'],
263 sub_name=cmd['sub_name'],
264 snap_name=cmd['snap_name'],
265 group_name=cmd.get('group_name', None))
11fdf7f2 266
81eedcae 267 def _cmd_fs_subvolume_snapshot_rm(self, inbuf, cmd):
494da23a
TL
268 return self.vc.remove_subvolume_snapshot(None, vol_name=cmd['vol_name'],
269 sub_name=cmd['sub_name'],
270 snap_name=cmd['snap_name'],
271 group_name=cmd.get('group_name', None),
272 force=cmd.get('force', False))