Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ceph: allow for non-positional optional CLI arguments #41509

Merged
merged 21 commits into from Jun 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
165987c
pybind/ceph_argparse: track a 'positional' property on cli args
liewegas May 21, 2021
b9a2a71
pybind/ceph_argparse: adjust help text for non-positional args
liewegas May 21, 2021
c441d35
command/cmdparse: use -- to separate positional from non-positional args
liewegas May 21, 2021
bcd821e
pybind/mgr/mgr_module: add separator for non-positional args
liewegas May 21, 2021
d2e8693
pybind/mgr/mgr_module: infer non-positional args
liewegas May 21, 2021
747eb7d
pybind/ceph_argparse: remove dead code
liewegas May 22, 2021
fb80427
pybind/ceph_argparse: stop parsing when we run out of positional args
liewegas May 22, 2021
27c2b83
mgr/orchestrator: reformat a few methods
liewegas May 22, 2021
b64e6dd
mgr/orchestrator: add end_positional to a few methods
liewegas May 22, 2021
5d8cfb1
mgr/orchestrator: clean up 'orch {daemon add,apply} rgw' args
liewegas May 22, 2021
4bc37ba
pybind/mgr/mgr_module: fix help desc formatting
liewegas May 22, 2021
fd77020
mgr/k8sevents: fix help strings
liewegas May 23, 2021
bd242c4
mon/MonCommands: convert some CephChoices to CephBool
liewegas May 23, 2021
c70a4f5
mgr: fix reweight-by-utilization cephbool flag
liewegas May 24, 2021
295a5f2
doc/_ext/ceph_commands: handle non-positional args in docs
liewegas May 25, 2021
218f4ce
mgr: make mgr commands compat with pre-quincy mon
liewegas May 29, 2021
8683ccc
qa/tasks/cephfs/test_nfs: fix export create test
liewegas Jun 1, 2021
b6b5ecc
mon/MonCommands: add -- seperator to example
liewegas Jun 1, 2021
ec293f3
common/cmdparse: emit proper json
liewegas Jun 1, 2021
ffce51a
mgr/nfs: fix 'nfs export create' argument order
liewegas Jun 4, 2021
6bd4df3
common/cmdparse: fix CephBool validation for tell commands
liewegas Jun 5, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 3 additions & 2 deletions doc/_ext/ceph_commands.py
Expand Up @@ -82,7 +82,7 @@ class CmdParam(object):

def __init__(self, type, name,
who=None, n=None, req=True, range=None, strings=None,
goodchars=None):
goodchars=None, positional=True):
self.type = type
self.name = name
self.who = who
Expand All @@ -91,6 +91,7 @@ def __init__(self, type, name,
self.range = range.split('|') if range else []
self.strings = strings.split('|') if strings else []
self.goodchars = goodchars
self.positional = positional != 'false'

assert who == None

Expand Down Expand Up @@ -200,7 +201,7 @@ def parse_args(args):

{%- if command.params %}
:Parameters:{% for param in command.params -%}
{{" -" | indent(12, not loop.first) }} **{{param.name}}**: {{ param.help() }}
{{" -" | indent(12, not loop.first) }} **{% if param.positional %}{{param.name}}{% else %}--{{param.name}}{% endif %}**: {{ param.help() }}
{% endfor %}
{% endif %}
:Ceph Module: {{ command.module }}
Expand Down
3 changes: 2 additions & 1 deletion qa/tasks/cephfs/test_nfs.py
Expand Up @@ -348,7 +348,8 @@ def test_create_multiple_exports(self):
# Export-3 for subvolume with r only
self._cmd('fs', 'subvolume', 'create', self.fs_name, 'sub_vol')
fs_path = self._cmd('fs', 'subvolume', 'getpath', self.fs_name, 'sub_vol').strip()
self._create_export(export_id='3', extra_cmd=[self.pseudo_path+'2', '--readonly', fs_path])
self._create_export(export_id='3', extra_cmd=[self.pseudo_path+'2', '--readonly',
'--path', fs_path])
# Export-4 for subvolume
self._create_export(export_id='4', extra_cmd=[self.pseudo_path+'3', fs_path])
# Check if exports gets listed
Expand Down
67 changes: 66 additions & 1 deletion src/common/cmdparse.cc
Expand Up @@ -138,13 +138,20 @@ dump_cmd_to_json(Formatter *f, uint64_t features, const string& cmd)

stringstream ss(cmd);
std::string word;
bool positional = true;

while (std::getline(ss, word, ' ')) {
if (word == "--") {
liewegas marked this conversation as resolved.
Show resolved Hide resolved
positional = false;
continue;
}

// if no , or =, must be a plain word to put out
if (word.find_first_of(",=") == string::npos) {
f->dump_string("arg", word);
continue;
}

// accumulate descriptor keywords in desckv
auto desckv = cmddesc_get_args(word);
// name the individual desc object based on the name key
Expand All @@ -168,8 +175,20 @@ dump_cmd_to_json(Formatter *f, uint64_t features, const string& cmd)
}

// dump all the keys including name into the array
if (!positional) {
desckv["positional"] = "false";
}
for (auto [key, value] : desckv) {
f->dump_string(key, value);
if (key == "positional") {
if (!HAVE_FEATURE(features, SERVER_QUINCY)) {
continue;
}
f->dump_bool(key, value == "true" || value == "True");
} else if (key == "req" && HAVE_FEATURE(features, SERVER_QUINCY)) {
f->dump_bool(key, value == "true" || value == "True");
} else {
f->dump_string(key, value);
}
}
f->close_section(); // attribute object for individual desc
}
Expand Down Expand Up @@ -550,6 +569,30 @@ bool validate_str_arg(std::string_view value,
}
}

bool validate_bool(CephContext *cct,
const cmdmap_t& cmdmap,
const arg_desc_t& desc,
const std::string_view name,
const std::string_view type,
std::ostream& os)
{
bool v;
try {
if (!cmd_getval(cmdmap, string(name), v)) {
tchaikov marked this conversation as resolved.
Show resolved Hide resolved
if (auto req = desc.find("req");
req != end(desc) && req->second == "false") {
return true;
} else {
os << "missing required parameter: '" << name << "'";
return false;
}
}
return true;
} catch (const bad_cmd_get& e) {
return false;
}
}

template<bool is_vector,
typename T,
typename Value = std::conditional_t<is_vector,
Expand Down Expand Up @@ -629,6 +672,9 @@ bool validate_cmd(CephContext* cct,
} else if (type == "CephFloat") {
return !validate_arg<false, double>(cct, cmdmap, arg_desc,
name, type, os);
} else if (type == "CephBool") {
return !validate_bool(cct, cmdmap, arg_desc,
name, type, os);
} else {
return !validate_arg<false, string>(cct, cmdmap, arg_desc,
name, type, os);
Expand Down Expand Up @@ -669,4 +715,23 @@ bool cmd_getval(const cmdmap_t& cmdmap,
return false;
}

bool cmd_getval_compat_cephbool(
const cmdmap_t& cmdmap,
const std::string& k, bool& val)
tchaikov marked this conversation as resolved.
Show resolved Hide resolved
{
try {
return cmd_getval(cmdmap, k, val);
} catch (bad_cmd_get& e) {
// try as legacy/compat CephChoices
std::string t;
if (!cmd_getval(cmdmap, k, t)) {
return false;
}
std::string expected = "--"s + k;
std::replace(expected.begin(), expected.end(), '_', '-');
val = (t == expected);
return true;
}
}

}
4 changes: 4 additions & 0 deletions src/common/cmdparse.h
Expand Up @@ -59,6 +59,10 @@ struct bad_cmd_get : public std::exception {
bool cmd_getval(const cmdmap_t& cmdmap,
const std::string& k, bool& val);

bool cmd_getval_compat_cephbool(
const cmdmap_t& cmdmap,
const std::string& k, bool& val);

template <typename T>
bool cmd_getval(const cmdmap_t& cmdmap,
const std::string& k, T& val)
Expand Down
2 changes: 1 addition & 1 deletion src/mgr/DaemonServer.cc
Expand Up @@ -1443,7 +1443,7 @@ bool DaemonServer::_handle_command(
return true;
}
bool no_increasing = false;
cmd_getval(cmdctx->cmdmap, "no_increasing", no_increasing);
cmd_getval_compat_cephbool(cmdctx->cmdmap, "no_increasing", no_increasing);
string out_str;
mempool::osdmap::map<int32_t, uint32_t> new_weights;
r = cluster_state.with_osdmap_and_pgmap([&](const OSDMap &osdmap, const PGMap& pgmap) {
Expand Down
6 changes: 3 additions & 3 deletions src/mgr/MgrCommands.h
Expand Up @@ -111,7 +111,7 @@ COMMAND("osd reweight-by-utilization " \
"name=oload,type=CephInt,req=false " \
"name=max_change,type=CephFloat,req=false " \
"name=max_osds,type=CephInt,req=false " \
"name=no_increasing,type=CephChoices,strings=--no-increasing,req=false",\
"name=no_increasing,type=CephBool,req=false",\
"reweight OSDs by utilization [overload-percentage-for-consideration, default 120]", \
"osd", "rw")
COMMAND("osd test-reweight-by-utilization " \
Expand Down Expand Up @@ -181,7 +181,7 @@ COMMAND("service status",
"dump service state", "service", "r")

COMMAND("config show " \
"name=who,type=CephString name=key,type=CephString,req=False",
"name=who,type=CephString name=key,type=CephString,req=false",
"Show running configuration",
"mgr", "r")
COMMAND("config show-with-defaults " \
Expand All @@ -203,7 +203,7 @@ COMMAND("device ls-by-host name=host,type=CephString",
"mgr", "r")
COMMAND("device set-life-expectancy name=devid,type=CephString "\
"name=from,type=CephString "\
"name=to,type=CephString,req=False",
"name=to,type=CephString,req=false",
"Set predicted device life expectancy",
"mgr", "rw")
COMMAND("device rm-life-expectancy name=devid,type=CephString",
Expand Down
7 changes: 7 additions & 0 deletions src/mgr/MgrStandby.cc
Expand Up @@ -12,6 +12,7 @@
*/

#include <Python.h>
#include <boost/algorithm/string/replace.hpp>

#include "common/errno.h"
#include "common/signal.h"
Expand Down Expand Up @@ -258,6 +259,12 @@ void MgrStandby::send_beacon()
std::vector<MonCommand> commands = mgr_commands;
std::vector<MonCommand> py_commands = py_module_registry.get_commands();
commands.insert(commands.end(), py_commands.begin(), py_commands.end());
if (monc.monmap.min_mon_release < ceph_release_t::quincy) {
dout(10) << " stripping out positional=false quincy-ism" << dendl;
for (auto& i : commands) {
boost::replace_all(i.cmdstring, ",positional=false", "");
}
}
m->set_command_descs(commands);
dout(4) << "going active, including " << m->get_command_descs().size()
<< " commands in beacon" << dendl;
Expand Down
8 changes: 4 additions & 4 deletions src/mon/MgrMonitor.cc
Expand Up @@ -1186,18 +1186,18 @@ bool MgrMonitor::prepare_command(MonOpRequestRef op)
ss << "module '" << module << "' is already enabled (always-on)";
goto out;
}
string force;
cmd_getval(cmdmap, "force", force);
bool force = false;
cmd_getval_compat_cephbool(cmdmap, "force", force);
if (!pending_map.all_support_module(module) &&
force != "--force") {
!force) {
ss << "all mgr daemons do not support module '" << module << "', pass "
<< "--force to force enablement";
r = -ENOENT;
goto out;
}

std::string can_run_error;
if (force != "--force" && !pending_map.can_run_module(module, &can_run_error)) {
if (!force && !pending_map.can_run_module(module, &can_run_error)) {
ss << "module '" << module << "' reports that it cannot run on the active "
"manager daemon: " << can_run_error << " (pass --force to force "
"enablement)";
Expand Down
24 changes: 16 additions & 8 deletions src/mon/MonCommands.h
Expand Up @@ -77,7 +77,9 @@
*
* COMMAND("auth add "
* "name=entity,type=CephString "
* "name=caps,type=CephString,n=N,req=false",
* "name=caps,type=CephString,n=N,req=false "
* "-- "
* "name=some_option,type=CephString,req=false",
* "add auth info for <name> from input file, or random key "
* "if no input given, and/or any caps specified in the command")
*
Expand All @@ -88,6 +90,12 @@
* enters auth add client.admin 'mon rwx' 'osd *'. The result will be a
* JSON object like {"prefix":"auth add", "entity":"client.admin",
* "caps":["mon rwx", "osd *"]}.
*
* The -- separates positional from non-positional (and, by implication,
* optional) arguments. Note that CephBool is assumed to be non-positional
* and will also implicitly mark that any following arguments are
* non-positional.
*
* Note that
* - string literals are accumulated into 'prefix'
* - n=1 descriptors are given normal string or int object values
Expand Down Expand Up @@ -474,7 +482,7 @@ COMMAND_WITH_FLAG("mon remove "
"remove monitor named <name>", "mon", "rw",
FLAG(DEPRECATED))
COMMAND("mon feature ls "
"name=with_value,type=CephChoices,strings=--with-value,req=false",
"name=with_value,type=CephBool,req=false",
"list available mon map features to be set/unset",
"mon", "r")
COMMAND("mon feature set "
Expand Down Expand Up @@ -750,7 +758,7 @@ COMMAND("osd crush rule rename "
"rename crush rule <srcname> to <dstname>",
"osd", "rw")
COMMAND("osd crush tree "
"name=shadow,type=CephChoices,strings=--show-shadow,req=false",
"name=show_shadow,type=CephBool,req=false",
"dump crush buckets and items in a tree view",
"osd", "r")
COMMAND("osd crush ls name=node,type=CephString,goodchars=[A-Za-z0-9-_.]",
Expand Down Expand Up @@ -1166,7 +1174,7 @@ COMMAND("osd force_recovery_stretch_mode " \
COMMAND("osd tier add "
"name=pool,type=CephPoolname "
"name=tierpool,type=CephPoolname "
"name=force_nonempty,type=CephChoices,strings=--force-nonempty,req=false",
"name=force_nonempty,type=CephBool,req=false",
"add the tier <tierpool> (the second one) to base pool <pool> (the first one)",
"osd", "rw")
COMMAND("osd tier rm "
Expand Down Expand Up @@ -1256,7 +1264,7 @@ COMMAND("mgr services",
"mgr", "r")
COMMAND("mgr module enable "
"name=module,type=CephString "
"name=force,type=CephChoices,strings=--force,req=false",
"name=force,type=CephBool,req=false",
"enable mgr module", "mgr", "rw")
COMMAND("mgr module disable "
"name=module,type=CephString",
Expand Down Expand Up @@ -1286,7 +1294,7 @@ COMMAND("config rm"
"config", "rw")
COMMAND("config get "
"name=who,type=CephString "
"name=key,type=CephString,req=False",
"name=key,type=CephString,req=false",
"Show configuration option(s) for an entity",
"config", "r")
COMMAND("config dump",
Expand All @@ -1302,7 +1310,7 @@ COMMAND("config ls",
COMMAND("config assimilate-conf",
"Assimilate options from a conf, and return a new, minimal conf file",
"config", "rw")
COMMAND("config log name=num,type=CephInt,req=False",
COMMAND("config log name=num,type=CephInt,req=false",
"Show recent history of config changes",
"config", "r")
COMMAND("config reset "
Expand Down Expand Up @@ -1352,7 +1360,7 @@ COMMAND_WITH_FLAG("connection scores reset",
"mon", "rwx",
FLAG(TELL))
COMMAND_WITH_FLAG("sync_force "
"name=validate,type=CephChoices,strings=--yes-i-really-mean-it,req=false",
"name=yes_i_really_mean_it,type=CephBool,req=false",
"force sync of and clear monitor store",
"mon", "rw",
FLAG(TELL))
Expand Down
12 changes: 9 additions & 3 deletions src/mon/Monitor.cc
Expand Up @@ -337,9 +337,15 @@ int Monitor::do_admin_command(
} else if (command == "quorum_status") {
_quorum_status(f, out);
} else if (command == "sync_force") {
string validate;
if ((!cmd_getval(cmdmap, "validate", validate)) ||
(validate != "--yes-i-really-mean-it")) {
bool validate = false;
if (!cmd_getval(cmdmap, "yes_i_really_mean_it", validate)) {
std::string v;
if (cmd_getval(cmdmap, "validate", v) &&
v == "--yes-i-really-mean-it") {
validate = true;
}
}
if (!validate) {
err << "are you SURE? this will mean the monitor store will be erased "
"the next time the monitor is restarted. pass "
"'--yes-i-really-mean-it' if you really do.";
Expand Down
6 changes: 1 addition & 5 deletions src/mon/MonmapMonitor.cc
Expand Up @@ -397,11 +397,7 @@ bool MonmapMonitor::preprocess_command(MonOpRequestRef op)
} else if (prefix == "mon feature ls") {

bool list_with_value = false;
string with_value;
if (cmd_getval(cmdmap, "with_value", with_value) &&
with_value == "--with-value") {
list_with_value = true;
}
cmd_getval_compat_cephbool(cmdmap, "with_value", list_with_value);

MonMap *p = mon.monmap;

Expand Down
21 changes: 13 additions & 8 deletions src/mon/OSDMonitor.cc
Expand Up @@ -6656,9 +6656,14 @@ bool OSDMonitor::preprocess_command(MonOpRequestRef op)
rs << "\n";
rdata.append(rs.str());
} else if (prefix == "osd crush tree") {
string shadow;
cmd_getval(cmdmap, "shadow", shadow);
bool show_shadow = shadow == "--show-shadow";
bool show_shadow = false;
if (!cmd_getval_compat_cephbool(cmdmap, "show_shadow", show_shadow)) {
std::string shadow;
if (cmd_getval(cmdmap, "shadow", shadow) &&
shadow == "--show-shadow") {
show_shadow = true;
}
}
boost::scoped_ptr<Formatter> f(Formatter::create(format));
if (f) {
f->open_object_section("crush_tree");
Expand Down Expand Up @@ -12961,11 +12966,11 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
}

// make sure new tier is empty
string force_nonempty;
cmd_getval(cmdmap, "force_nonempty", force_nonempty);
bool force_nonempty = false;
cmd_getval_compat_cephbool(cmdmap, "force_nonempty", force_nonempty);
const pool_stat_t *pstats = mon.mgrstatmon()->get_pool_stat(tierpool_id);
if (pstats && pstats->stats.sum.num_objects != 0 &&
force_nonempty != "--force-nonempty") {
!force_nonempty) {
ss << "tier pool '" << tierpoolstr << "' is not empty; --force-nonempty to force";
err = -ENOTEMPTY;
goto reply;
Expand All @@ -12977,8 +12982,8 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
goto reply;
}
if ((!tp->removed_snaps.empty() || !tp->snaps.empty()) &&
((force_nonempty != "--force-nonempty") ||
(!g_conf()->mon_debug_unsafe_allow_tier_with_nonempty_snaps))) {
(!force_nonempty ||
!g_conf()->mon_debug_unsafe_allow_tier_with_nonempty_snaps)) {
ss << "tier pool '" << tierpoolstr << "' has snapshot state; it cannot be added as a tier without breaking the pool";
err = -ENOTEMPTY;
goto reply;
Expand Down