1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
6 #include "tools/rbd/ArgumentTypes.h"
7 #include "tools/rbd/Shell.h"
8 #include "tools/rbd/Utils.h"
9 #include "include/rbd_types.h"
10 #include "cls/rbd/cls_rbd_types.h"
11 #include "common/errno.h"
12 #include "common/Formatter.h"
13 #include "common/TextTable.h"
19 namespace at
= argument_types
;
20 namespace po
= boost::program_options
;
22 static const std::string
GROUP_SPEC("group-spec");
23 static const std::string
GROUP_SNAP_SPEC("group-snap-spec");
25 static const std::string
GROUP_NAME("group");
26 static const std::string
DEST_GROUP_NAME("dest-group");
28 static const std::string
GROUP_POOL_NAME("group-" + at::POOL_NAME
);
29 static const std::string
IMAGE_POOL_NAME("image-" + at::POOL_NAME
);
31 void add_group_option(po::options_description
*opt
,
32 at::ArgumentModifier modifier
) {
33 std::string name
= GROUP_NAME
;
34 std::string description
= at::get_description_prefix(modifier
) + "group name";
36 case at::ARGUMENT_MODIFIER_NONE
:
37 case at::ARGUMENT_MODIFIER_SOURCE
:
39 case at::ARGUMENT_MODIFIER_DEST
:
40 name
= DEST_GROUP_NAME
;
46 (name
.c_str(), po::value
<std::string
>(), description
.c_str());
49 void add_prefixed_pool_option(po::options_description
*opt
,
50 const std::string
&prefix
) {
51 std::string name
= prefix
+ "-" + at::POOL_NAME
;
52 std::string description
= prefix
+ " pool name";
55 (name
.c_str(), po::value
<std::string
>(), description
.c_str());
58 void add_prefixed_namespace_option(po::options_description
*opt
,
59 const std::string
&prefix
) {
60 std::string name
= prefix
+ "-" + at::NAMESPACE_NAME
;
61 std::string description
= prefix
+ " namespace name";
64 (name
.c_str(), po::value
<std::string
>(), description
.c_str());
67 void add_group_spec_options(po::options_description
*pos
,
68 po::options_description
*opt
,
69 at::ArgumentModifier modifier
,
71 at::add_pool_option(opt
, modifier
);
72 at::add_namespace_option(opt
, modifier
);
73 add_group_option(opt
, modifier
);
76 ((get_name_prefix(modifier
) + GROUP_SPEC
).c_str(),
77 (get_description_prefix(modifier
) + "group specification\n" +
78 "(example: [<pool-name>/[<namespace>/]]<group-name>)").c_str());
80 add_snap_option(opt
, modifier
);
82 ((get_name_prefix(modifier
) + GROUP_SNAP_SPEC
).c_str(),
83 (get_description_prefix(modifier
) + "group specification\n" +
84 "(example: [<pool-name>/[<namespace>/]]<group-name>@<snap-name>)").c_str());
88 int execute_create(const po::variables_map
&vm
,
89 const std::vector
<std::string
> &ceph_global_init_args
) {
92 std::string pool_name
;
93 std::string namespace_name
;
94 std::string group_name
;
96 int r
= utils::get_pool_generic_snapshot_names(
97 vm
, at::ARGUMENT_MODIFIER_NONE
, &arg_index
, at::POOL_NAME
, &pool_name
,
98 &namespace_name
, GROUP_NAME
, "group", &group_name
, nullptr, true,
99 utils::SNAPSHOT_PRESENCE_NONE
, utils::SPEC_VALIDATION_FULL
);
104 librados::Rados rados
;
105 librados::IoCtx io_ctx
;
107 r
= utils::init(pool_name
, namespace_name
, &rados
, &io_ctx
);
112 r
= rbd
.group_create(io_ctx
, group_name
.c_str());
114 std::cerr
<< "rbd: create error: " << cpp_strerror(r
) << std::endl
;
121 int execute_list(const po::variables_map
&vm
,
122 const std::vector
<std::string
> &ceph_global_init_args
) {
123 std::string pool_name
;
124 std::string namespace_name
;
125 size_t arg_index
= 0;
126 int r
= utils::get_pool_and_namespace_names(vm
, false, &pool_name
,
127 &namespace_name
, &arg_index
);
132 at::Format::Formatter formatter
;
133 r
= utils::get_formatter(vm
, &formatter
);
137 Formatter
*f
= formatter
.get();
139 librados::Rados rados
;
140 librados::IoCtx io_ctx
;
141 r
= utils::init(pool_name
, namespace_name
, &rados
, &io_ctx
);
147 std::vector
<std::string
> names
;
148 r
= rbd
.group_list(io_ctx
, &names
);
153 f
->open_array_section("groups");
154 for (auto i
: names
) {
156 f
->dump_string("name", i
);
158 std::cout
<< i
<< std::endl
;
168 int execute_remove(const po::variables_map
&vm
,
169 const std::vector
<std::string
> &ceph_global_init_args
) {
170 size_t arg_index
= 0;
172 std::string pool_name
;
173 std::string namespace_name
;
174 std::string group_name
;
176 int r
= utils::get_pool_generic_snapshot_names(
177 vm
, at::ARGUMENT_MODIFIER_NONE
, &arg_index
, at::POOL_NAME
, &pool_name
,
178 &namespace_name
, GROUP_NAME
, "group", &group_name
, nullptr, true,
179 utils::SNAPSHOT_PRESENCE_NONE
, utils::SPEC_VALIDATION_FULL
);
184 librados::Rados rados
;
185 librados::IoCtx io_ctx
;
187 r
= utils::init(pool_name
, namespace_name
, &rados
, &io_ctx
);
193 r
= rbd
.group_remove(io_ctx
, group_name
.c_str());
195 std::cerr
<< "rbd: remove error: " << cpp_strerror(r
) << std::endl
;
202 int execute_rename(const po::variables_map
&vm
,
203 const std::vector
<std::string
> &ceph_global_init_args
) {
204 size_t arg_index
= 0;
206 std::string pool_name
;
207 std::string namespace_name
;
208 std::string group_name
;
210 int r
= utils::get_pool_generic_snapshot_names(
211 vm
, at::ARGUMENT_MODIFIER_NONE
, &arg_index
, at::POOL_NAME
, &pool_name
,
212 &namespace_name
, GROUP_NAME
, "group", &group_name
, nullptr, true,
213 utils::SNAPSHOT_PRESENCE_NONE
, utils::SPEC_VALIDATION_FULL
);
218 std::string dest_pool_name
;
219 std::string dest_namespace_name
;
220 std::string dest_group_name
;
222 r
= utils::get_pool_generic_snapshot_names(
223 vm
, at::ARGUMENT_MODIFIER_DEST
, &arg_index
, at::DEST_POOL_NAME
,
224 &dest_pool_name
, &dest_namespace_name
, DEST_GROUP_NAME
, "group",
225 &dest_group_name
, nullptr, true, utils::SNAPSHOT_PRESENCE_NONE
,
226 utils::SPEC_VALIDATION_FULL
);
231 if (pool_name
!= dest_pool_name
) {
232 std::cerr
<< "rbd: group rename across pools not supported" << std::endl
233 << "source pool: " << pool_name
<< ", dest pool: "
234 << dest_pool_name
<< std::endl
;
236 } else if (namespace_name
!= dest_namespace_name
) {
237 std::cerr
<< "rbd: group rename across namespaces not supported"
239 << "source namespace: " << namespace_name
<< ", dest namespace: "
240 << dest_namespace_name
<< std::endl
;
244 librados::Rados rados
;
245 librados::IoCtx io_ctx
;
246 r
= utils::init(pool_name
, namespace_name
, &rados
, &io_ctx
);
252 r
= rbd
.group_rename(io_ctx
, group_name
.c_str(),
253 dest_group_name
.c_str());
256 std::cerr
<< "rbd: failed to rename group: "
257 << cpp_strerror(r
) << std::endl
;
264 int execute_add(const po::variables_map
&vm
,
265 const std::vector
<std::string
> &ceph_global_init_args
) {
266 size_t arg_index
= 0;
268 std::string group_pool_name
;
269 std::string group_namespace_name
;
270 std::string group_name
;
272 int r
= utils::get_pool_generic_snapshot_names(
273 vm
, at::ARGUMENT_MODIFIER_NONE
, &arg_index
, GROUP_POOL_NAME
,
274 &group_pool_name
, &group_namespace_name
, GROUP_NAME
, "group", &group_name
,
275 nullptr, true, utils::SNAPSHOT_PRESENCE_NONE
, utils::SPEC_VALIDATION_FULL
);
280 std::string image_pool_name
;
281 std::string image_namespace_name
;
282 std::string image_name
;
284 r
= utils::get_pool_generic_snapshot_names(
285 vm
, at::ARGUMENT_MODIFIER_NONE
, &arg_index
, IMAGE_POOL_NAME
,
286 &image_pool_name
, &image_namespace_name
, at::IMAGE_NAME
, "image",
287 &image_name
, nullptr, true, utils::SNAPSHOT_PRESENCE_NONE
,
288 utils::SPEC_VALIDATION_FULL
);
293 if (group_namespace_name
!= image_namespace_name
) {
294 std::cerr
<< "rbd: group and image namespace must match." << std::endl
;
298 librados::Rados rados
;
299 librados::IoCtx cg_io_ctx
;
300 r
= utils::init(group_pool_name
, group_namespace_name
, &rados
, &cg_io_ctx
);
305 librados::IoCtx image_io_ctx
;
306 r
= utils::init(image_pool_name
, group_namespace_name
, &rados
, &image_io_ctx
);
312 r
= rbd
.group_image_add(cg_io_ctx
, group_name
.c_str(),
313 image_io_ctx
, image_name
.c_str());
315 std::cerr
<< "rbd: add image error: " << cpp_strerror(r
) << std::endl
;
322 int execute_remove_image(const po::variables_map
&vm
,
323 const std::vector
<std::string
> &ceph_global_init_args
) {
324 size_t arg_index
= 0;
326 std::string group_pool_name
;
327 std::string group_namespace_name
;
328 std::string group_name
;
330 int r
= utils::get_pool_generic_snapshot_names(
331 vm
, at::ARGUMENT_MODIFIER_NONE
, &arg_index
, GROUP_POOL_NAME
,
332 &group_pool_name
, &group_namespace_name
, GROUP_NAME
, "group", &group_name
,
333 nullptr, true, utils::SNAPSHOT_PRESENCE_NONE
, utils::SPEC_VALIDATION_FULL
);
338 std::string image_pool_name
;
339 std::string image_namespace_name
;
340 std::string image_name
;
341 std::string image_id
;
343 if (vm
.count(at::IMAGE_ID
)) {
344 image_id
= vm
[at::IMAGE_ID
].as
<std::string
>();
347 r
= utils::get_pool_generic_snapshot_names(
348 vm
, at::ARGUMENT_MODIFIER_NONE
, &arg_index
, IMAGE_POOL_NAME
,
349 &image_pool_name
, &image_namespace_name
, at::IMAGE_NAME
, "image",
350 &image_name
, nullptr, image_id
.empty(), utils::SNAPSHOT_PRESENCE_NONE
,
351 utils::SPEC_VALIDATION_FULL
);
356 if (group_namespace_name
!= image_namespace_name
) {
357 std::cerr
<< "rbd: group and image namespace must match." << std::endl
;
359 } else if (!image_id
.empty() && !image_name
.empty()) {
360 std::cerr
<< "rbd: trying to access image using both name and id. "
365 librados::Rados rados
;
366 librados::IoCtx cg_io_ctx
;
367 r
= utils::init(group_pool_name
, group_namespace_name
, &rados
, &cg_io_ctx
);
372 librados::IoCtx image_io_ctx
;
373 r
= utils::init(image_pool_name
, group_namespace_name
, &rados
, &image_io_ctx
);
379 if (image_id
.empty()) {
380 r
= rbd
.group_image_remove(cg_io_ctx
, group_name
.c_str(),
381 image_io_ctx
, image_name
.c_str());
383 r
= rbd
.group_image_remove_by_id(cg_io_ctx
, group_name
.c_str(),
384 image_io_ctx
, image_id
.c_str());
387 std::cerr
<< "rbd: remove image error: " << cpp_strerror(r
) << std::endl
;
394 int execute_list_images(const po::variables_map
&vm
,
395 const std::vector
<std::string
> &ceph_global_init_args
) {
396 size_t arg_index
= 0;
397 std::string pool_name
;
398 std::string namespace_name
;
399 std::string group_name
;
401 int r
= utils::get_pool_generic_snapshot_names(
402 vm
, at::ARGUMENT_MODIFIER_NONE
, &arg_index
, at::POOL_NAME
, &pool_name
,
403 &namespace_name
, GROUP_NAME
, "group", &group_name
, nullptr, true,
404 utils::SNAPSHOT_PRESENCE_NONE
, utils::SPEC_VALIDATION_FULL
);
409 at::Format::Formatter formatter
;
410 r
= utils::get_formatter(vm
, &formatter
);
414 Formatter
*f
= formatter
.get();
416 librados::Rados rados
;
417 librados::IoCtx io_ctx
;
418 r
= utils::init(pool_name
, namespace_name
, &rados
, &io_ctx
);
424 std::vector
<librbd::group_image_info_t
> images
;
426 r
= rbd
.group_image_list(io_ctx
, group_name
.c_str(), &images
,
427 sizeof(librbd::group_image_info_t
));
435 std::sort(images
.begin(), images
.end(),
436 [](const librbd::group_image_info_t
&lhs
,
437 const librbd::group_image_info_t
&rhs
) {
438 if (lhs
.pool
!= rhs
.pool
) {
439 return lhs
.pool
< rhs
.pool
;
441 return lhs
.name
< rhs
.name
;
446 f
->open_array_section("images");
448 for (auto image
: images
) {
449 std::string image_name
= image
.name
;
450 int state
= image
.state
;
451 std::string state_string
;
452 if (RBD_GROUP_IMAGE_STATE_INCOMPLETE
== state
) {
453 state_string
= "incomplete";
456 std::string pool_name
= "";
458 librados::Rados
rados(io_ctx
);
459 librados::IoCtx pool_io_ctx
;
460 r
= rados
.ioctx_create2(image
.pool
, pool_io_ctx
);
462 pool_name
= "<missing image pool " + stringify(image
.pool
) + ">";
464 pool_name
= pool_io_ctx
.get_pool_name();
468 f
->open_object_section("image");
469 f
->dump_string("image", image_name
);
470 f
->dump_string("pool", pool_name
);
471 f
->dump_string("namespace", io_ctx
.get_namespace());
472 f
->dump_int("state", state
);
475 std::cout
<< pool_name
<< "/";
476 if (!io_ctx
.get_namespace().empty()) {
477 std::cout
<< io_ctx
.get_namespace() << "/";
479 std::cout
<< image_name
<< " " << state_string
<< std::endl
;
491 int execute_group_snap_create(const po::variables_map
&vm
,
492 const std::vector
<std::string
> &global_args
) {
493 size_t arg_index
= 0;
495 std::string pool_name
;
496 std::string namespace_name
;
497 std::string group_name
;
498 std::string snap_name
;
500 int r
= utils::get_pool_generic_snapshot_names(
501 vm
, at::ARGUMENT_MODIFIER_NONE
, &arg_index
, at::POOL_NAME
, &pool_name
,
502 &namespace_name
, GROUP_NAME
, "group", &group_name
, &snap_name
, true,
503 utils::SNAPSHOT_PRESENCE_REQUIRED
, utils::SPEC_VALIDATION_FULL
);
509 r
= utils::get_snap_create_flags(vm
, &flags
);
514 librados::IoCtx io_ctx
;
515 librados::Rados rados
;
517 r
= utils::init(pool_name
, namespace_name
, &rados
, &io_ctx
);
523 r
= rbd
.group_snap_create2(io_ctx
, group_name
.c_str(), snap_name
.c_str(),
532 int execute_group_snap_remove(const po::variables_map
&vm
,
533 const std::vector
<std::string
> &global_args
) {
534 size_t arg_index
= 0;
536 std::string pool_name
;
537 std::string namespace_name
;
538 std::string group_name
;
539 std::string snap_name
;
541 int r
= utils::get_pool_generic_snapshot_names(
542 vm
, at::ARGUMENT_MODIFIER_NONE
, &arg_index
, at::POOL_NAME
, &pool_name
,
543 &namespace_name
, GROUP_NAME
, "group", &group_name
, &snap_name
, true,
544 utils::SNAPSHOT_PRESENCE_REQUIRED
, utils::SPEC_VALIDATION_FULL
);
549 librados::IoCtx io_ctx
;
550 librados::Rados rados
;
552 r
= utils::init(pool_name
, namespace_name
, &rados
, &io_ctx
);
558 r
= rbd
.group_snap_remove(io_ctx
, group_name
.c_str(), snap_name
.c_str());
560 std::cerr
<< "rbd: failed to remove group snapshot: "
561 << cpp_strerror(r
) << std::endl
;
568 int execute_group_snap_rename(const po::variables_map
&vm
,
569 const std::vector
<std::string
> &global_args
) {
570 size_t arg_index
= 0;
572 std::string pool_name
;
573 std::string namespace_name
;
574 std::string group_name
;
575 std::string source_snap_name
;
577 int r
= utils::get_pool_generic_snapshot_names(
578 vm
, at::ARGUMENT_MODIFIER_NONE
, &arg_index
, at::POOL_NAME
, &pool_name
,
579 &namespace_name
, GROUP_NAME
, "group", &group_name
, &source_snap_name
, true,
580 utils::SNAPSHOT_PRESENCE_REQUIRED
, utils::SPEC_VALIDATION_FULL
);
585 std::string dest_snap_name
;
586 if (vm
.count(at::DEST_SNAPSHOT_NAME
)) {
587 dest_snap_name
= vm
[at::DEST_SNAPSHOT_NAME
].as
<std::string
>();
590 if (dest_snap_name
.empty()) {
591 dest_snap_name
= utils::get_positional_argument(vm
, arg_index
++);
594 if (dest_snap_name
.empty()) {
595 std::cerr
<< "rbd: destination snapshot name was not specified"
600 r
= utils::validate_snapshot_name(at::ARGUMENT_MODIFIER_DEST
, dest_snap_name
,
601 utils::SNAPSHOT_PRESENCE_REQUIRED
,
602 utils::SPEC_VALIDATION_SNAP
);
606 librados::Rados rados
;
607 librados::IoCtx io_ctx
;
608 r
= utils::init(pool_name
, namespace_name
, &rados
, &io_ctx
);
614 r
= rbd
.group_snap_rename(io_ctx
, group_name
.c_str(),
615 source_snap_name
.c_str(), dest_snap_name
.c_str());
618 std::cerr
<< "rbd: failed to rename group snapshot: "
619 << cpp_strerror(r
) << std::endl
;
626 int execute_group_snap_list(const po::variables_map
&vm
,
627 const std::vector
<std::string
> &ceph_global_args
) {
628 size_t arg_index
= 0;
629 std::string pool_name
;
630 std::string namespace_name
;
631 std::string group_name
;
633 int r
= utils::get_pool_generic_snapshot_names(
634 vm
, at::ARGUMENT_MODIFIER_NONE
, &arg_index
, at::POOL_NAME
, &pool_name
,
635 &namespace_name
, GROUP_NAME
, "group", &group_name
, nullptr, true,
636 utils::SNAPSHOT_PRESENCE_NONE
, utils::SPEC_VALIDATION_FULL
);
641 at::Format::Formatter formatter
;
642 r
= utils::get_formatter(vm
, &formatter
);
646 Formatter
*f
= formatter
.get();
648 librados::Rados rados
;
649 librados::IoCtx io_ctx
;
650 r
= utils::init(pool_name
, namespace_name
, &rados
, &io_ctx
);
656 std::vector
<librbd::group_snap_info_t
> snaps
;
658 r
= rbd
.group_snap_list(io_ctx
, group_name
.c_str(), &snaps
,
659 sizeof(librbd::group_snap_info_t
));
670 f
->open_array_section("group_snaps");
672 t
.define_column("NAME", TextTable::LEFT
, TextTable::LEFT
);
673 t
.define_column("STATUS", TextTable::LEFT
, TextTable::RIGHT
);
676 for (auto i
: snaps
) {
677 std::string snap_name
= i
.name
;
679 std::string state_string
;
680 if (RBD_GROUP_SNAP_STATE_INCOMPLETE
== state
) {
681 state_string
= "incomplete";
689 f
->open_object_section("group_snap");
690 f
->dump_string("snapshot", snap_name
);
691 f
->dump_string("state", state_string
);
694 t
<< snap_name
<< state_string
<< TextTable::endrow
;
701 } else if (snaps
.size()) {
707 int execute_group_snap_rollback(const po::variables_map
&vm
,
708 const std::vector
<std::string
> &global_args
) {
709 size_t arg_index
= 0;
711 std::string group_name
;
712 std::string namespace_name
;
713 std::string pool_name
;
714 std::string snap_name
;
716 int r
= utils::get_pool_generic_snapshot_names(
717 vm
, at::ARGUMENT_MODIFIER_NONE
, &arg_index
, at::POOL_NAME
, &pool_name
,
718 &namespace_name
, GROUP_NAME
, "group", &group_name
, &snap_name
, true,
719 utils::SNAPSHOT_PRESENCE_REQUIRED
, utils::SPEC_VALIDATION_FULL
);
724 librados::IoCtx io_ctx
;
725 librados::Rados rados
;
727 r
= utils::init(pool_name
, namespace_name
, &rados
, &io_ctx
);
733 utils::ProgressContext
pc("Rolling back to group snapshot",
734 vm
[at::NO_PROGRESS
].as
<bool>());
735 r
= rbd
.group_snap_rollback_with_progress(io_ctx
, group_name
.c_str(),
736 snap_name
.c_str(), pc
);
739 std::cerr
<< "rbd: rollback group to snapshot failed: "
740 << cpp_strerror(r
) << std::endl
;
748 void get_create_arguments(po::options_description
*positional
,
749 po::options_description
*options
) {
750 add_group_spec_options(positional
, options
, at::ARGUMENT_MODIFIER_NONE
,
754 void get_remove_arguments(po::options_description
*positional
,
755 po::options_description
*options
) {
756 add_group_spec_options(positional
, options
, at::ARGUMENT_MODIFIER_NONE
,
760 void get_list_arguments(po::options_description
*positional
,
761 po::options_description
*options
) {
762 at::add_pool_options(positional
, options
, true);
763 at::add_format_options(options
);
766 void get_rename_arguments(po::options_description
*positional
,
767 po::options_description
*options
) {
768 add_group_spec_options(positional
, options
, at::ARGUMENT_MODIFIER_SOURCE
,
770 add_group_spec_options(positional
, options
, at::ARGUMENT_MODIFIER_DEST
,
774 void get_add_arguments(po::options_description
*positional
,
775 po::options_description
*options
) {
776 positional
->add_options()
778 "group specification\n"
779 "(example: [<pool-name>/[<namespace>/]]<group-name>)");
781 add_prefixed_pool_option(options
, "group");
782 add_prefixed_namespace_option(options
, "group");
783 add_group_option(options
, at::ARGUMENT_MODIFIER_NONE
);
785 positional
->add_options()
786 (at::IMAGE_SPEC
.c_str(),
787 "image specification\n"
788 "(example: [<pool-name>/[<namespace>/]]<image-name>)");
790 add_prefixed_pool_option(options
, "image");
791 add_prefixed_namespace_option(options
, "image");
792 at::add_image_option(options
, at::ARGUMENT_MODIFIER_NONE
);
794 at::add_pool_option(options
, at::ARGUMENT_MODIFIER_NONE
,
795 " unless overridden");
798 void get_remove_image_arguments(po::options_description
*positional
,
799 po::options_description
*options
) {
800 positional
->add_options()
802 "group specification\n"
803 "(example: [<pool-name>/[<namespace>/]]<group-name>)");
805 add_prefixed_pool_option(options
, "group");
806 add_prefixed_namespace_option(options
, "group");
807 add_group_option(options
, at::ARGUMENT_MODIFIER_NONE
);
809 positional
->add_options()
810 (at::IMAGE_SPEC
.c_str(),
811 "image specification\n"
812 "(example: [<pool-name>/[<namespace>/]]<image-name>)");
814 add_prefixed_pool_option(options
, "image");
815 add_prefixed_namespace_option(options
, "image");
816 at::add_image_option(options
, at::ARGUMENT_MODIFIER_NONE
);
818 at::add_pool_option(options
, at::ARGUMENT_MODIFIER_NONE
,
819 " unless overridden");
820 at::add_image_id_option(options
);
823 void get_list_images_arguments(po::options_description
*positional
,
824 po::options_description
*options
) {
825 at::add_format_options(options
);
826 add_group_spec_options(positional
, options
, at::ARGUMENT_MODIFIER_NONE
,
830 void get_group_snap_create_arguments(po::options_description
*positional
,
831 po::options_description
*options
) {
832 add_group_spec_options(positional
, options
, at::ARGUMENT_MODIFIER_NONE
,
834 at::add_snap_create_options(options
);
837 void get_group_snap_remove_arguments(po::options_description
*positional
,
838 po::options_description
*options
) {
839 add_group_spec_options(positional
, options
, at::ARGUMENT_MODIFIER_NONE
,
843 void get_group_snap_rename_arguments(po::options_description
*positional
,
844 po::options_description
*options
) {
845 add_group_spec_options(positional
, options
, at::ARGUMENT_MODIFIER_NONE
,
848 positional
->add_options()
849 (at::DEST_SNAPSHOT_NAME
.c_str(),
850 "destination snapshot name\n(example: <snap-name>)");
851 at::add_snap_option(options
, at::ARGUMENT_MODIFIER_DEST
);
854 void get_group_snap_list_arguments(po::options_description
*positional
,
855 po::options_description
*options
) {
856 at::add_format_options(options
);
857 add_group_spec_options(positional
, options
, at::ARGUMENT_MODIFIER_NONE
,
861 void get_group_snap_rollback_arguments(po::options_description
*positional
,
862 po::options_description
*options
) {
863 at::add_no_progress_option(options
);
864 add_group_spec_options(positional
, options
, at::ARGUMENT_MODIFIER_NONE
,
868 Shell::Action
action_create(
869 {"group", "create"}, {}, "Create a group.",
870 "", &get_create_arguments
, &execute_create
);
871 Shell::Action
action_remove(
872 {"group", "remove"}, {"group", "rm"}, "Delete a group.",
873 "", &get_remove_arguments
, &execute_remove
);
874 Shell::Action
action_list(
875 {"group", "list"}, {"group", "ls"}, "List rbd groups.",
876 "", &get_list_arguments
, &execute_list
);
877 Shell::Action
action_rename(
878 {"group", "rename"}, {}, "Rename a group within pool.",
879 "", &get_rename_arguments
, &execute_rename
);
880 Shell::Action
action_add(
881 {"group", "image", "add"}, {}, "Add an image to a group.",
882 "", &get_add_arguments
, &execute_add
);
883 Shell::Action
action_remove_image(
884 {"group", "image", "remove"}, {"group", "image", "rm"},
885 "Remove an image from a group.", "",
886 &get_remove_image_arguments
, &execute_remove_image
);
887 Shell::Action
action_list_images(
888 {"group", "image", "list"}, {"group", "image", "ls"},
889 "List images in a group.", "",
890 &get_list_images_arguments
, &execute_list_images
);
891 Shell::Action
action_group_snap_create(
892 {"group", "snap", "create"}, {}, "Make a snapshot of a group.",
893 "", &get_group_snap_create_arguments
, &execute_group_snap_create
);
894 Shell::Action
action_group_snap_remove(
895 {"group", "snap", "remove"}, {"group", "snap", "rm"},
896 "Remove a snapshot from a group.",
897 "", &get_group_snap_remove_arguments
, &execute_group_snap_remove
);
898 Shell::Action
action_group_snap_rename(
899 {"group", "snap", "rename"}, {}, "Rename group's snapshot.",
900 "", &get_group_snap_rename_arguments
, &execute_group_snap_rename
);
901 Shell::Action
action_group_snap_list(
902 {"group", "snap", "list"}, {"group", "snap", "ls"},
903 "List snapshots of a group.",
904 "", &get_group_snap_list_arguments
, &execute_group_snap_list
);
905 Shell::Action
action_group_snap_rollback(
906 {"group", "snap", "rollback"}, {},
907 "Rollback group to snapshot.",
908 "", &get_group_snap_rollback_arguments
, &execute_group_snap_rollback
);
911 } // namespace action