Currently at least five commands have optional positional arguments.
Overloading po::value<std::string>()->default_value("") for this
is a bit sneaky but nothing better fits into the existing Shell.cc
framework.
Note that strictly speaking "[<interval>] [<start-time>]" should be
"[<interval> [<start-time>]]" but we aren't doing that here because
"ceph" command doesn't do it either.
Fixes: https://tracker.ceph.com/issues/54191
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
rbd help mirror image enable
usage: rbd mirror image enable [--pool <pool>] [--namespace <namespace>]
[--image <image>]
- <image-spec> <mode>
+ <image-spec> [<mode>]
Enable RBD mirroring for an image.
[--pool <pool>]
[--namespace <namespace>]
[--image <image>]
- <interval> <start-time>
+ <interval> [<start-time>]
Add mirror snapshot schedule.
[--pool <pool>]
[--namespace <namespace>]
[--image <image>]
- <interval> <start-time>
+ [<interval>] [<start-time>]
Remove mirror snapshot schedule.
rbd help trash purge schedule add
usage: rbd trash purge schedule add [--pool <pool>] [--namespace <namespace>]
- <interval> <start-time>
+ <interval> [<start-time>]
Add trash purge schedule.
rbd help trash purge schedule remove
usage: rbd trash purge schedule remove
[--pool <pool>] [--namespace <namespace>]
- <interval> <start-time>
+ [<interval>] [<start-time>]
Remove trash purge schedule.
#include "tools/rbd/OptionPrinter.h"
#include "tools/rbd/IndentStream.h"
+#include "include/ceph_assert.h"
namespace rbd {
for (size_t i = 0; i < m_positional.options().size(); ++i) {
std::stringstream option;
+ // we overload po::value<std::string>()->default_value("") to signify
+ // an optional positional argument (purely for help printing purposes)
+ boost::any v;
+ bool required = !m_positional.options()[i]->semantic()->apply_default(v);
+ if (!required) {
+ auto ptr = boost::any_cast<std::string>(&v);
+ ceph_assert(ptr && ptr->empty());
+ option << "[";
+ }
option << "<" << m_positional.options()[i]->long_name() << ">";
if (m_positional.options()[i]->semantic()->max_tokens() > 1) {
option << " [<" << m_positional.options()[i]->long_name() << "> ...]";
}
+ if (!required) {
+ option << "]";
+ }
max_option_width = std::max(max_option_width, option.str().size());
positionals.emplace_back(option.str());
}
}
-void add_schedule_options(po::options_description *positional) {
- positional->add_options()
- ("interval", "schedule interval");
+void add_schedule_options(po::options_description *positional,
+ bool mandatory) {
+ if (mandatory) {
+ positional->add_options()
+ ("interval", "schedule interval");
+ } else {
+ positional->add_options()
+ ("interval", po::value<std::string>()->default_value(""),
+ "schedule interval");
+ }
positional->add_options()
- ("start-time", "schedule start time");
+ ("start-time", po::value<std::string>()->default_value(""),
+ "schedule start time");
}
int get_schedule_args(const po::variables_map &vm, bool mandatory,
void normalize_level_spec_args(std::map<std::string, std::string> *args);
void add_schedule_options(
- boost::program_options::options_description *positional);
+ boost::program_options::options_description *positional, bool mandatory);
int get_schedule_args(const boost::program_options::variables_map &vm,
bool mandatory, std::map<std::string, std::string> *args);
po::options_description *options) {
at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE);
positional->add_options()
- ("mode", "mirror image mode (journal or snapshot) [default: journal]");
+ ("mode", po::value<std::string>()->default_value(""),
+ "mirror image mode (journal or snapshot) [default: journal]");
}
void get_arguments_disable(po::options_description *positional,
void get_arguments_add(po::options_description *positional,
po::options_description *options) {
add_level_spec_options(options);
- add_schedule_options(positional);
+ add_schedule_options(positional, true);
}
int execute_add(const po::variables_map &vm,
void get_arguments_remove(po::options_description *positional,
po::options_description *options) {
add_level_spec_options(options);
- add_schedule_options(positional);
+ add_schedule_options(positional, false);
}
int execute_remove(const po::variables_map &vm,
void get_arguments_add(po::options_description *positional,
po::options_description *options) {
add_level_spec_options(options, false);
- add_schedule_options(positional);
+ add_schedule_options(positional, true);
}
int execute_add(const po::variables_map &vm,
void get_arguments_remove(po::options_description *positional,
po::options_description *options) {
add_level_spec_options(options, false);
- add_schedule_options(positional);
+ add_schedule_options(positional, false);
}
int execute_remove(const po::variables_map &vm,