]> git.proxmox.com Git - ceph.git/blame - ceph/src/spdk/scripts/spdkcli/ui_node.py
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / spdk / scripts / spdkcli / ui_node.py
CommitLineData
11fdf7f2
TL
1from configshell_fb import ConfigNode, ExecutionError
2from uuid import UUID
3from rpc.client import JSONRPCException
4import json
5
6
7def convert_bytes_to_human(size):
8 if not size:
9 return ""
10 for x in ["bytes", "K", "M", "G", "T"]:
11 if size < 1024.0:
12 return "%3.1f%s" % (size, x)
13 size /= 1024.0
14
15
16class UINode(ConfigNode):
17 def __init__(self, name, parent=None, shell=None):
18 ConfigNode.__init__(self, name, parent, shell)
19
20 def refresh(self):
21 for child in self.children:
22 child.refresh()
23
9f95a23c
TL
24 def refresh_node(self):
25 self.refresh()
26
11fdf7f2
TL
27 def ui_command_refresh(self):
28 self.refresh()
29
30 def ui_command_ll(self, path=None, depth=None):
31 """
32 Alias for ls.
33 """
34 self.ui_command_ls(path, depth)
35
36 def execute_command(self, command, pparams=[], kparams={}):
37 try:
38 result = ConfigNode.execute_command(self, command,
39 pparams, kparams)
9f95a23c
TL
40 except Exception as e:
41 raise e
11fdf7f2
TL
42 else:
43 self.shell.log.debug("Command %s succeeded." % command)
44 return result
9f95a23c
TL
45 finally:
46 if self.shell.interactive and\
47 command in ["create", "delete", "delete_all", "add_initiator",
f67539c2
TL
48 "allow_any_host", "bdev_split_create", "add_lun",
49 "iscsi_target_node_add_pg_ig_maps", "remove_target", "add_secret",
50 "bdev_split_delete", "bdev_pmem_delete_pool",
51 "bdev_pmem_create_pool", "delete_secret_all",
9f95a23c 52 "delete_initiator", "set_auth", "delete_secret",
f67539c2 53 "iscsi_target_node_remove_pg_ig_maps", "load_config",
9f95a23c
TL
54 "load_subsystem_config"]:
55 self.get_root().refresh()
56 self.refresh_node()
11fdf7f2
TL
57
58
59class UIBdevs(UINode):
60 def __init__(self, parent):
61 UINode.__init__(self, "bdevs", parent)
62 self.refresh()
63
64 def refresh(self):
65 self._children = set([])
66 UIMallocBdev(self)
67 UIAIOBdev(self)
68 UILvolBdev(self)
69 UINvmeBdev(self)
70 UINullBdev(self)
71 UIErrorBdev(self)
72 UISplitBdev(self)
73 UIPmemBdev(self)
74 UIRbdBdev(self)
75 UIiSCSIBdev(self)
76 UIVirtioBlkBdev(self)
77 UIVirtioScsiBdev(self)
9f95a23c 78 UIRaidBdev(self)
11fdf7f2
TL
79
80
81class UILvolStores(UINode):
82 def __init__(self, parent):
83 UINode.__init__(self, "lvol_stores", parent)
84 self.refresh()
85
86 def refresh(self):
87 self._children = set([])
f67539c2 88 for lvs in self.get_root().bdev_lvol_get_lvstores():
11fdf7f2
TL
89 UILvsObj(lvs, self)
90
9f95a23c
TL
91 def delete(self, name, uuid):
92 if name is None and uuid is None:
93 self.shell.log.error("Please specify one of the identifiers: "
94 "lvol store name or UUID")
f67539c2 95 self.get_root().bdev_lvol_delete_lvstore(lvs_name=name, uuid=uuid)
9f95a23c 96
11fdf7f2
TL
97 def ui_command_create(self, name, bdev_name, cluster_size=None):
98 """
99 Creates logical volume store on target bdev.
100
101 Arguments:
102 name - Friendly name to use alongside with UUID identifier.
103 bdev_name - On which bdev to create the lvol store.
104 cluster_size - Cluster size to use when creating lvol store, in bytes. Default: 4194304.
105 """
106
107 cluster_size = self.ui_eval_param(cluster_size, "number", None)
f67539c2 108 self.get_root().bdev_lvol_create_lvstore(lvs_name=name, bdev_name=bdev_name, cluster_sz=cluster_size)
11fdf7f2
TL
109
110 def ui_command_delete(self, name=None, uuid=None):
111 """
112 Deletes logical volume store from configuration.
113 This will also delete all logical volume bdevs created on this lvol store!
114
115 Arguments:
116 name - Friendly name of the logical volume store to be deleted.
117 uuid - UUID number of the logical volume store to be deleted.
118 """
9f95a23c
TL
119 self.delete(name, uuid)
120
121 def ui_command_delete_all(self):
122 rpc_messages = ""
123 for lvs in self._children:
124 try:
125 self.delete(None, lvs.lvs.uuid)
126 except JSONRPCException as e:
127 rpc_messages += e.message
128 if rpc_messages:
129 raise JSONRPCException(rpc_messages)
11fdf7f2
TL
130
131 def summary(self):
132 return "Lvol stores: %s" % len(self.children), None
133
134
135class UIBdev(UINode):
136 def __init__(self, name, parent):
137 UINode.__init__(self, name, parent)
138 self.refresh()
139
140 def refresh(self):
141 self._children = set([])
f67539c2 142 for bdev in self.get_root().bdev_get_bdevs(self.name):
11fdf7f2
TL
143 UIBdevObj(bdev, self)
144
145 def ui_command_get_bdev_iostat(self, name=None):
f67539c2 146 ret = self.get_root().bdev_get_iostat(name=name)
9f95a23c
TL
147 self.shell.log.info(json.dumps(ret, indent=2))
148
149 def ui_command_delete_all(self):
150 """Delete all bdevs from this tree node."""
151 rpc_messages = ""
152 for bdev in self._children:
153 try:
154 self.delete(bdev.name)
155 except JSONRPCException as e:
156 rpc_messages += e.message
157 if rpc_messages:
158 raise JSONRPCException(rpc_messages)
11fdf7f2
TL
159
160 def summary(self):
161 return "Bdevs: %d" % len(self.children), None
162
163
164class UIMallocBdev(UIBdev):
165 def __init__(self, parent):
166 UIBdev.__init__(self, "malloc", parent)
167
9f95a23c 168 def delete(self, name):
f67539c2 169 self.get_root().bdev_malloc_delete(name=name)
9f95a23c 170
11fdf7f2
TL
171 def ui_command_create(self, size, block_size, name=None, uuid=None):
172 """
173 Construct a Malloc bdev.
174
175 Arguments:
176 size - Size in megabytes.
177 block_size - Integer, block size to use when constructing bdev.
178 name - Optional argument. Custom name to use for bdev. If not provided
179 then name will be "MallocX" where X is next available ID.
180 uuid - Optional parameter. Custom UUID to use. If empty then random
181 will be generated.
182 """
183
184 size = self.ui_eval_param(size, "number", None)
185 block_size = self.ui_eval_param(block_size, "number", None)
9f95a23c
TL
186 ret_name = self.get_root().create_malloc_bdev(num_blocks=size * 1024 * 1024 // block_size,
187 block_size=block_size,
188 name=name, uuid=uuid)
189 self.shell.log.info(ret_name)
11fdf7f2
TL
190
191 def ui_command_delete(self, name):
192 """
193 Deletes malloc bdev from configuration.
194
195 Arguments:
196 name - Is a unique identifier of the malloc bdev to be deleted - UUID number or name alias.
197 """
9f95a23c 198 self.delete(name)
11fdf7f2
TL
199
200
201class UIAIOBdev(UIBdev):
202 def __init__(self, parent):
203 UIBdev.__init__(self, "aio", parent)
204
9f95a23c 205 def delete(self, name):
f67539c2 206 self.get_root().bdev_aio_delete(name=name)
9f95a23c 207
11fdf7f2
TL
208 def ui_command_create(self, name, filename, block_size):
209 """
210 Construct an AIO bdev.
211 Backend file must exist before trying to create an AIO bdev.
212
213 Arguments:
214 name - Optional argument. Custom name to use for bdev. If not provided
215 then name will be "MallocX" where X is next available ID.
216 filename - Path to AIO backend.
217 block_size - Integer, block size to use when constructing bdev.
218 """
219
220 block_size = self.ui_eval_param(block_size, "number", None)
f67539c2 221 ret_name = self.get_root().bdev_aio_create(name=name,
9f95a23c
TL
222 block_size=int(block_size),
223 filename=filename)
224 self.shell.log.info(ret_name)
11fdf7f2
TL
225
226 def ui_command_delete(self, name):
227 """
228 Deletes aio bdev from configuration.
229
230 Arguments:
231 name - Is a unique identifier of the aio bdev to be deleted - UUID number or name alias.
232 """
9f95a23c 233 self.delete(name)
11fdf7f2
TL
234
235
236class UILvolBdev(UIBdev):
237 def __init__(self, parent):
238 UIBdev.__init__(self, "logical_volume", parent)
239
9f95a23c 240 def delete(self, name):
f67539c2 241 self.get_root().bdev_lvol_delete(name=name)
9f95a23c 242
11fdf7f2
TL
243 def ui_command_create(self, name, size, lvs, thin_provision=None):
244 """
245 Construct a Logical Volume bdev.
246
247 Arguments:
248 name - Friendly name to use for creating logical volume bdev.
249 size - Size in megabytes.
250 lvs - Identifier of logical volume store on which the bdev should be
251 created. Can be either a friendly name or UUID.
252 thin_provision - Whether the bdev should be thick or thin provisioned.
253 Default is False, and created bdevs are thick-provisioned.
254 """
255 uuid = None
256 lvs_name = None
257 try:
258 UUID(lvs)
259 uuid = lvs
260 except ValueError:
261 lvs_name = lvs
262
263 size = self.ui_eval_param(size, "number", None)
264 size *= (1024 * 1024)
265 thin_provision = self.ui_eval_param(thin_provision, "bool", False)
266
9f95a23c
TL
267 ret_uuid = self.get_root().create_lvol_bdev(lvol_name=name, size=size,
268 lvs_name=lvs_name, uuid=uuid,
269 thin_provision=thin_provision)
270 self.shell.log.info(ret_uuid)
11fdf7f2
TL
271
272 def ui_command_delete(self, name):
273 """
274 Deletes lvol bdev from configuration.
275
276 Arguments:
277 name - Is a unique identifier of the lvol bdev to be deleted - UUID number or name alias.
278 """
9f95a23c 279 self.delete(name)
11fdf7f2
TL
280
281
282class UINvmeBdev(UIBdev):
283 def __init__(self, parent):
284 UIBdev.__init__(self, "nvme", parent)
285
9f95a23c 286 def delete(self, name):
f67539c2 287 self.get_root().bdev_nvme_detach_controller(name=name)
9f95a23c 288
11fdf7f2
TL
289 def ui_command_create(self, name, trtype, traddr,
290 adrfam=None, trsvcid=None, subnqn=None):
11fdf7f2
TL
291 if "rdma" in trtype and None in [adrfam, trsvcid, subnqn]:
292 self.shell.log.error("Using RDMA transport type."
293 "Please provide arguments for adrfam, trsvcid and subnqn.")
9f95a23c
TL
294 ret_name = self.get_root().create_nvme_bdev(name=name, trtype=trtype,
295 traddr=traddr, adrfam=adrfam,
296 trsvcid=trsvcid, subnqn=subnqn)
297 self.shell.log.info(ret_name)
298
299 def ui_command_delete_all(self):
300 rpc_messages = ""
301 ctrlrs = [x.name for x in self._children]
302 ctrlrs = [x.rsplit("n", 1)[0] for x in ctrlrs]
303 ctrlrs = set(ctrlrs)
304 for ctrlr in ctrlrs:
305 try:
306 self.delete(ctrlr)
307 except JSONRPCException as e:
308 rpc_messages += e.messages
309 if rpc_messages:
310 raise JSONRPCException(rpc_messages)
11fdf7f2
TL
311
312 def ui_command_delete(self, name):
313 """
314 Deletes NVMe controller from configuration.
315
316 Arguments:
317 name - Is a unique identifier of the NVMe controller to be deleted.
318 """
9f95a23c 319 self.delete(name)
11fdf7f2
TL
320
321
322class UINullBdev(UIBdev):
323 def __init__(self, parent):
324 UIBdev.__init__(self, "null", parent)
325
9f95a23c 326 def delete(self, name):
f67539c2 327 self.get_root().bdev_null_delete(name=name)
9f95a23c 328
11fdf7f2
TL
329 def ui_command_create(self, name, size, block_size, uuid=None):
330 """
331 Construct a Null bdev.
332
333 Arguments:
334 name - Name to use for bdev.
335 size - Size in megabytes.
336 block_size - Integer, block size to use when constructing bdev.
337 uuid - Optional parameter. Custom UUID to use. If empty then random
338 will be generated.
339 """
340
341 size = self.ui_eval_param(size, "number", None)
342 block_size = self.ui_eval_param(block_size, "number", None)
343 num_blocks = size * 1024 * 1024 // block_size
f67539c2 344 ret_name = self.get_root().bdev_null_create(num_blocks=num_blocks,
9f95a23c
TL
345 block_size=block_size,
346 name=name, uuid=uuid)
347 self.shell.log.info(ret_name)
11fdf7f2
TL
348
349 def ui_command_delete(self, name):
350 """
351 Deletes null bdev from configuration.
352
353 Arguments:
354 name - Is a unique identifier of the null bdev to be deleted - UUID number or name alias.
355 """
9f95a23c 356 self.delete(name)
11fdf7f2
TL
357
358
359class UIErrorBdev(UIBdev):
360 def __init__(self, parent):
361 UIBdev.__init__(self, "error", parent)
362
9f95a23c 363 def delete(self, name):
f67539c2 364 self.get_root().bdev_error_delete(name=name)
9f95a23c 365
11fdf7f2
TL
366 def ui_command_create(self, base_name):
367 """
368 Construct a error injection bdev.
369
370 Arguments:
371 base_name - base bdev name on top of which error bdev will be created.
372 """
373
9f95a23c 374 self.get_root().create_error_bdev(base_name=base_name)
11fdf7f2
TL
375
376 def ui_command_delete(self, name):
377 """
378 Deletes error bdev from configuration.
379
380 Arguments:
381 name - Is a unique identifier of the error bdev to be deleted - UUID number or name alias.
382 """
9f95a23c 383 self.delete(name)
11fdf7f2
TL
384
385
386class UISplitBdev(UIBdev):
387 def __init__(self, parent):
388 UIBdev.__init__(self, "split_disk", parent)
389
9f95a23c
TL
390 def delete(self, name):
391 pass
392
f67539c2 393 def ui_command_bdev_split_create(self, base_bdev, split_count, split_size_mb=None):
11fdf7f2 394 """
f67539c2 395 Create split block devices from a base bdev.
11fdf7f2
TL
396
397 Arguments:
398 base_bdev - Name of bdev to split
399 split_count - Number of split bdevs to create
400 split_size_mb- Size of each split volume in MiB (optional)
401 """
402
403 split_count = self.ui_eval_param(split_count, "number", None)
404 split_size_mb = self.ui_eval_param(split_size_mb, "number", None)
405
f67539c2
TL
406 ret_name = self.get_root().bdev_split_create(base_bdev=base_bdev,
407 split_count=split_count,
408 split_size_mb=split_size_mb)
9f95a23c 409 self.shell.log.info(ret_name)
11fdf7f2 410
f67539c2
TL
411 def ui_command_bdev_split_delete(self, base_bdev):
412 """Delete split block devices associated with base bdev.
11fdf7f2
TL
413
414 Args:
415 base_bdev: name of previously split bdev
416 """
417
f67539c2 418 self.get_root().bdev_split_delete(base_bdev=base_bdev)
11fdf7f2
TL
419
420
421class UIPmemBdev(UIBdev):
422 def __init__(self, parent):
423 UIBdev.__init__(self, "pmemblk", parent)
424
9f95a23c 425 def delete(self, name):
f67539c2 426 self.get_root().bdev_pmem_delete(name=name)
9f95a23c 427
f67539c2 428 def ui_command_bdev_pmem_create_pool(self, pmem_file, total_size, block_size):
11fdf7f2
TL
429 total_size = self.ui_eval_param(total_size, "number", None)
430 block_size = self.ui_eval_param(block_size, "number", None)
431 num_blocks = int((total_size * 1024 * 1024) / block_size)
432
f67539c2
TL
433 self.get_root().bdev_pmem_create_pool(pmem_file=pmem_file,
434 num_blocks=num_blocks,
435 block_size=block_size)
11fdf7f2 436
f67539c2
TL
437 def ui_command_bdev_pmem_delete_pool(self, pmem_file):
438 self.get_root().bdev_pmem_delete_pool(pmem_file=pmem_file)
11fdf7f2 439
f67539c2
TL
440 def ui_command_bdev_pmem_get_pool_info(self, pmem_file):
441 ret = self.get_root().bdev_pmem_get_pool_info(pmem_file=pmem_file)
442 self.shell.log.info(json.dumps(ret, indent=2))
11fdf7f2
TL
443
444 def ui_command_create(self, pmem_file, name):
f67539c2 445 ret_name = self.get_root().bdev_pmem_create(pmem_file=pmem_file,
9f95a23c
TL
446 name=name)
447 self.shell.log.info(ret_name)
11fdf7f2
TL
448
449 def ui_command_delete(self, name):
450 """
451 Deletes pmem bdev from configuration.
452
453 Arguments:
454 name - Is a unique identifier of the pmem bdev to be deleted - UUID number or name alias.
455 """
9f95a23c 456 self.delete(name)
11fdf7f2
TL
457
458
459class UIRbdBdev(UIBdev):
460 def __init__(self, parent):
461 UIBdev.__init__(self, "rbd", parent)
462
9f95a23c 463 def delete(self, name):
f67539c2 464 self.get_root().bdev_rbd_delete(name=name)
9f95a23c 465
11fdf7f2
TL
466 def ui_command_create(self, pool_name, rbd_name, block_size, name=None):
467 block_size = self.ui_eval_param(block_size, "number", None)
468
9f95a23c
TL
469 ret_name = self.get_root().create_rbd_bdev(pool_name=pool_name,
470 rbd_name=rbd_name,
471 block_size=block_size,
472 name=name)
473 self.shell.log.info(ret_name)
11fdf7f2
TL
474
475 def ui_command_delete(self, name):
476 """
477 Deletes rbd bdev from configuration.
478
479 Arguments:
480 name - Is a unique identifier of the rbd bdev to be deleted - UUID number or name alias.
481 """
9f95a23c 482 self.delete(name)
11fdf7f2
TL
483
484
485class UIiSCSIBdev(UIBdev):
486 def __init__(self, parent):
487 UIBdev.__init__(self, "iscsi", parent)
488
9f95a23c 489 def delete(self, name):
f67539c2 490 self.get_root().bdev_iscsi_delete(name=name)
9f95a23c 491
11fdf7f2
TL
492 def ui_command_create(self, name, url, initiator_iqn):
493 """
494 Create iSCSI bdev in configuration by connecting to remote
495 iSCSI target.
496
497 Arguments:
498 name - name to be used as an ID for created iSCSI bdev.
499 url - iscsi url pointing to LUN on remote iSCSI target.
500 Example: iscsi://127.0.0.1:3260/iqn.2018-06.org.spdk/0.
501 initiator_iqn - IQN to use for initiating connection with the target.
502 """
9f95a23c
TL
503 ret_name = self.get_root().create_iscsi_bdev(name=name,
504 url=url,
505 initiator_iqn=initiator_iqn)
506 self.shell.log.info(ret_name)
11fdf7f2
TL
507
508 def ui_command_delete(self, name):
509 """
510 Deletes iSCSI bdev from configuration.
511
512 Arguments:
513 name - name of the iscsi bdev to be deleted.
514 """
9f95a23c 515 self.delete(name)
11fdf7f2
TL
516
517
518class UIVirtioBlkBdev(UIBdev):
519 def __init__(self, parent):
520 UIBdev.__init__(self, "virtioblk_disk", parent)
521
522 def ui_command_create(self, name, trtype, traddr,
523 vq_count=None, vq_size=None):
524
525 vq_count = self.ui_eval_param(vq_count, "number", None)
526 vq_size = self.ui_eval_param(vq_size, "number", None)
527
9f95a23c
TL
528 ret = self.get_root().create_virtio_dev(name=name,
529 trtype=trtype,
530 traddr=traddr,
531 dev_type="blk",
532 vq_count=vq_count,
533 vq_size=vq_size)
534
535 self.shell.log.info(ret)
11fdf7f2
TL
536
537 def ui_command_delete(self, name):
538 """
539 Deletes virtio scsi bdev from configuration.
540
541 Arguments:
542 name - Is a unique identifier of the virtio scsi bdev to be deleted - UUID number or name alias.
543 """
f67539c2 544 self.get_root().bdev_virtio_detach_controller(name=name)
11fdf7f2
TL
545
546
547class UIVirtioScsiBdev(UIBdev):
548 def __init__(self, parent):
549 UIBdev.__init__(self, "virtioscsi_disk", parent)
550
551 def refresh(self):
552 self._children = set([])
f67539c2 553 for bdev in self.get_root().bdev_virtio_scsi_get_devices():
11fdf7f2
TL
554 UIVirtioScsiBdevObj(bdev, self)
555
556 def ui_command_create(self, name, trtype, traddr,
557 vq_count=None, vq_size=None):
558
559 vq_count = self.ui_eval_param(vq_count, "number", None)
560 vq_size = self.ui_eval_param(vq_size, "number", None)
561
9f95a23c
TL
562 ret = self.get_root().create_virtio_dev(name=name,
563 trtype=trtype,
564 traddr=traddr,
565 dev_type="scsi",
566 vq_count=vq_count,
567 vq_size=vq_size)
11fdf7f2 568
9f95a23c 569 self.shell.log.info(ret)
11fdf7f2 570
9f95a23c 571 def ui_command_delete(self, name):
f67539c2 572 self.get_root().bdev_virtio_detach_controller(name=name)
11fdf7f2
TL
573
574
575class UIBdevObj(UINode):
576 def __init__(self, bdev, parent):
577 self.bdev = bdev
578 # Using bdev name also for lvol bdevs, which results in displying
579 # UUID instead of alias. This is because alias naming convention
580 # (lvol_store_name/lvol_bdev_name) conflicts with configshell paths
581 # ("/" as separator).
582 # Solution: show lvol alias in "summary field" for now.
583 # TODO: Possible next steps:
584 # - Either change default separator in tree for smth else
585 # - or add a UI command which would be able to autocomplete
586 # "cd" command based on objects alias and match is to the
587 # "main" bdev name.
588 UINode.__init__(self, self.bdev.name, parent)
589
590 def ui_command_show_details(self):
591 self.shell.log.info(json.dumps(vars(self.bdev), indent=2))
592
593 def summary(self):
594 size = convert_bytes_to_human(self.bdev.block_size * self.bdev.num_blocks)
595 size = "=".join(["Size", size])
596
597 in_use = "Not claimed"
598 if bool(self.bdev.claimed):
599 in_use = "Claimed"
600
601 alias = None
602 if self.bdev.aliases:
603 alias = self.bdev.aliases[0]
604
605 info = ", ".join([_f for _f in [alias, size, in_use] if _f])
606 return info, True
607
608
609class UIVirtioScsiBdevObj(UIBdevObj):
610 def __init__(self, bdev, parent):
611 UIBdevObj.__init__(self, bdev, parent)
612 self.refresh()
613
614 def refresh(self):
615 self._children = set([])
f67539c2 616 for bdev in self.get_root().bdev_get_bdevs("virtio_scsi_disk"):
11fdf7f2
TL
617 if self.bdev.name in bdev.name:
618 UIBdevObj(bdev, self)
619
620 def summary(self):
621 if "socket" in list(self.bdev.virtio.keys()):
622 info = self.bdev.virtio["socket"]
623 if "pci_address" in list(self.bdev.virtio.keys()):
624 info = self.bdev.virtio["pci_address"]
625 return info, True
626
627
628class UILvsObj(UINode):
629 def __init__(self, lvs, parent):
630 UINode.__init__(self, lvs.name, parent)
631 self.lvs = lvs
632
633 def ui_command_show_details(self):
634 self.shell.log.info(json.dumps(vars(self.lvs), indent=2))
635
636 def summary(self):
637 size = convert_bytes_to_human(self.lvs.total_data_clusters * self.lvs.cluster_size)
638 free = convert_bytes_to_human(self.lvs.free_clusters * self.lvs.cluster_size)
639 if not free:
640 free = "0"
641 size = "=".join(["Size", size])
642 free = "=".join(["Free", free])
643 info = ", ".join([str(size), str(free)])
644 return info, True
645
646
647class UIVhosts(UINode):
648 def __init__(self, parent):
649 UINode.__init__(self, "vhost", parent)
650 self.refresh()
651
652 def refresh(self):
653 self._children = set([])
654 self.get_root().list_vhost_ctrls()
655 UIVhostBlk(self)
656 UIVhostScsi(self)
657
658
659class UIVhost(UINode):
660 def __init__(self, name, parent):
661 UINode.__init__(self, name, parent)
662 self.refresh()
663
664 def ui_command_delete(self, name):
665 """
666 Delete a Vhost controller from configuration.
667
668 Arguments:
669 name - Controller name.
670 """
f67539c2 671 self.get_root().vhost_delete_controller(ctrlr=name)
11fdf7f2
TL
672
673
674class UIVhostBlk(UIVhost):
675 def __init__(self, parent):
676 UIVhost.__init__(self, "block", parent)
677 self.refresh()
678
679 def refresh(self):
680 self._children = set([])
f67539c2 681 for ctrlr in self.get_root().vhost_get_controllers(ctrlr_type=self.name):
11fdf7f2
TL
682 UIVhostBlkCtrlObj(ctrlr, self)
683
684 def ui_command_create(self, name, bdev, cpumask=None, readonly=False):
685 """
f67539c2 686 Create a Vhost BLK controller.
11fdf7f2
TL
687
688 Arguments:
689 name - Controller name.
690 bdev - Which bdev to attach to the controller.
691 cpumask - Optional. Integer to specify mask of CPUs to use.
692 Default: 1.
693 readonly - Whether controller should be read only or not.
694 Default: False.
695 """
f67539c2 696 self.get_root().vhost_create_blk_controller(ctrlr=name,
9f95a23c
TL
697 dev_name=bdev,
698 cpumask=cpumask,
699 readonly=bool(readonly))
11fdf7f2
TL
700
701
702class UIVhostScsi(UIVhost):
703 def __init__(self, parent):
704 UIVhost.__init__(self, "scsi", parent)
705 self.refresh()
706
707 def refresh(self):
708 self._children = set([])
f67539c2 709 for ctrlr in self.get_root().vhost_get_controllers(ctrlr_type=self.name):
11fdf7f2
TL
710 UIVhostScsiCtrlObj(ctrlr, self)
711
712 def ui_command_create(self, name, cpumask=None):
713 """
f67539c2 714 Create a Vhost SCSI controller.
11fdf7f2
TL
715
716 Arguments:
717 name - Controller name.
718 cpumask - Optional. Integer to specify mask of CPUs to use.
719 Default: 1.
720 """
f67539c2 721 self.get_root().vhost_create_scsi_controller(ctrlr=name,
9f95a23c 722 cpumask=cpumask)
11fdf7f2
TL
723
724
725class UIVhostCtrl(UINode):
726 # Base class for SCSI and BLK controllers, do not instantiate
727 def __init__(self, ctrlr, parent):
728 self.ctrlr = ctrlr
729 UINode.__init__(self, self.ctrlr.ctrlr, parent)
730 self.refresh()
731
732 def ui_command_show_details(self):
733 self.shell.log.info(json.dumps(vars(self.ctrlr), indent=2))
734
735 def ui_command_set_coalescing(self, delay_base_us, iops_threshold):
736 delay_base_us = self.ui_eval_param(delay_base_us, "number", None)
737 iops_threshold = self.ui_eval_param(iops_threshold, "number", None)
738
f67539c2 739 self.get_root().vhost_controller_set_coalescing(ctrlr=self.ctrlr.ctrlr,
9f95a23c
TL
740 delay_base_us=delay_base_us,
741 iops_threshold=iops_threshold)
11fdf7f2
TL
742
743
744class UIVhostScsiCtrlObj(UIVhostCtrl):
745 def refresh(self):
746 self._children = set([])
747 for lun in self.ctrlr.backend_specific["scsi"]:
748 UIVhostTargetObj(lun, self)
749
750 def ui_command_remove_target(self, target_num):
751 """
752 Remove target node from SCSI controller.
753
754 Arguments:
755 target_num - Integer identifier of target node to delete.
756 """
f67539c2
TL
757 self.get_root().vhost_scsi_controller_remove_target(ctrlr=self.ctrlr.ctrlr,
758 scsi_target_num=int(target_num))
759 for ctrlr in self.get_root().vhost_get_controllers(ctrlr_type="scsi"):
9f95a23c
TL
760 if ctrlr.ctrlr == self.ctrlr.ctrlr:
761 self.ctrlr = ctrlr
11fdf7f2
TL
762
763 def ui_command_add_lun(self, target_num, bdev_name):
764 """
765 Add LUN to SCSI target node.
766 Currently only one LUN (which is LUN ID 0) per target is supported.
767 Adding LUN to not existing target node will create that node.
768
769 Arguments:
770 target_num - Integer identifier of target node to modify.
771 bdev - Which bdev to add as LUN.
772 """
f67539c2
TL
773 self.get_root().vhost_scsi_controller_add_target(ctrlr=self.ctrlr.ctrlr,
774 scsi_target_num=int(target_num),
775 bdev_name=bdev_name)
776 for ctrlr in self.get_root().vhost_get_controllers(ctrlr_type="scsi"):
9f95a23c
TL
777 if ctrlr.ctrlr == self.ctrlr.ctrlr:
778 self.ctrlr = ctrlr
11fdf7f2
TL
779
780 def summary(self):
781 info = self.ctrlr.socket
782 return info, True
783
784
785class UIVhostBlkCtrlObj(UIVhostCtrl):
786 def refresh(self):
787 self._children = set([])
788 UIVhostLunDevObj(self.ctrlr.backend_specific["block"]["bdev"], self)
789
790 def summary(self):
791 ro = None
792 if self.ctrlr.backend_specific["block"]["readonly"]:
793 ro = "Readonly"
794 info = ", ".join([_f for _f in [self.ctrlr.socket, ro] if _f])
795 return info, True
796
797
798class UIVhostTargetObj(UINode):
799 def __init__(self, target, parent):
800 self.target = target
801 # Next line: configshell does not allow paths with spaces.
802 UINode.__init__(self, target["target_name"].replace(" ", "_"), parent)
803 self.refresh()
804
805 def refresh(self):
806 self._children = set([])
807 for target in self.target["luns"]:
808 UIVhostLunDevObj(target["bdev_name"], self)
809
810 def ui_command_show_details(self):
811 self.shell.log.info(json.dumps(self.target, indent=2))
812
813 def summary(self):
814 luns = "LUNs: %s" % len(self.target["luns"])
815 id = "TargetID: %s" % self.target["scsi_dev_num"]
816 info = ",".join([luns, id])
817 return info, True
818
819
820class UIVhostLunDevObj(UINode):
821 def __init__(self, name, parent):
822 UINode.__init__(self, name, parent)
9f95a23c
TL
823
824
825class UIRaidBdev(UIBdev):
826 def __init__(self, parent):
827 UIBdev.__init__(self, "raid_volume", parent)
828
829 def delete(self, name):
f67539c2 830 self.get_root().bdev_raid_delete(name=name)
9f95a23c
TL
831
832 def ui_command_create(self, name, raid_level, base_bdevs, strip_size_kb):
833 """
834 Creates a raid bdev of the provided base_bdevs
835
836 Arguments:
837 name - raid bdev name
838 raid_level - raid level, supported values 0
839 base_bdevs - base bdevs name, whitespace separated list in quotes
840 strip_size_kb - strip size of raid bdev in KB, supported values like 8, 16, 32, 64, 128, 256, etc
841 """
842 base_bdevs_array = []
843 for u in base_bdevs.strip().split(" "):
844 base_bdevs_array.append(u)
845
9f95a23c
TL
846 strip_size_kb = self.ui_eval_param(strip_size_kb, "number", None)
847
f67539c2
TL
848 ret_name = self.get_root().bdev_raid_create(name=name,
849 raid_level=raid_level,
850 base_bdevs=base_bdevs_array,
851 strip_size_kb=strip_size_kb)
9f95a23c
TL
852 self.shell.log.info(ret_name)
853
854 def ui_command_delete(self, name):
855 """
856 Deletes this raid bdev object
857
858 Arguments:
859 name - raid bdev name
860 """
861 self.delete(name)