Skip to content

Commit

Permalink
Merge pull request ceph#14858 from dmick/wip-config-dump
Browse files Browse the repository at this point in the history
mon/ConfigKeyService: add 'config-key dump' to show keys and vals

Reviewed-by: Sage Weil <[email protected]>
  • Loading branch information
yuriw committed May 2, 2017
2 parents f7cf9d1 + 557b2a7 commit 3a68017
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 3 deletions.
10 changes: 8 additions & 2 deletions doc/man/8/ceph.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Synopsis
| **ceph** **compact**
| **ceph** **config-key** [ *del* | *exists* | *get* | *list* | *put* ] ...
| **ceph** **config-key** [ *del* | *exists* | *get* | *list* | *dump* | *put* ] ...
| **ceph** **daemon** *<name>* \| *<path>* *<command>* ...
Expand Down Expand Up @@ -201,7 +201,13 @@ Usage::

ceph config-key list

Subcommand ``put`` puts configuration key and values.
Subcommand ``dump`` dumps configuration keys and values.

Usage::

ceph config-key dump

Subcommand ``put`` puts configuration key and value.

Usage::

Expand Down
73 changes: 72 additions & 1 deletion qa/workunits/mon/test_mon_config_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import argparse
import base64
import errno
import json
import logging
import os
import random
Expand Down Expand Up @@ -47,11 +48,20 @@
(8192, -errno.EFBIG)
]

# tests will be randomly selected from the keys here, and the test
# suboperation will be randomly selected from the list in the values
# here. i.e. 'exists/existing' would test that a key the test put into
# the store earlier actually does still exist in the config store,
# and that's a separate test case from 'exists/enoent', which tests
# nonexistence of a key known to not be present.

OPS = {
'put': ['existing', 'new'],
'del': ['existing', 'enoent'],
'exists': ['existing', 'enoent'],
'get': ['existing', 'enoent']
'get': ['existing', 'enoent'],
'list': ['existing', 'enoent'],
'dump': ['existing', 'enoent'],
}

CONFIG_PUT = [] # list: keys
Expand Down Expand Up @@ -386,6 +396,67 @@ def main():
k=key, sz=cnt, es=CONFIG_EXISTING[key])
destroy_tmp_file(file_path)
continue

elif op == 'list' or op == 'dump':
expected = 0
cmd = [op]
key = None

if sop == 'existing':
if len(CONFIG_EXISTING) == 0:
op_log.debug('no existing keys; continue')
continue
key = rnd.choice(CONFIG_PUT)
assert key in CONFIG_EXISTING, \
"key '{k_}' not in CONFIG_EXISTING".format(k_=key)

if sop == 'enoent':
for x in range(0, 10):
key = base64.b64encode(os.urandom(20)).decode()
if key not in CONFIG_EXISTING:
break
key = None
if key is None:
op_log.error('unable to generate an unique key -- try again later.')
continue
assert key not in CONFIG_PUT and key not in CONFIG_EXISTING, \
'key {k} was not supposed to exist!'.format(k=key)

assert key is not None, \
'key must be != None'

file_path = gen_tmp_file_path(rnd)
cmd += ['-o', file_path]
op_log.debug('key: {k}'.format(k=key))
run_cmd(cmd, expects=expected)
try:
temp_file = open(file_path, 'r+')
except IOError as err:
if err.errno == errno.ENOENT:
assert CONFIG_EXISTING[key] == 0, \
"error opening '{fp}': {e}".format(fp=file_path, e=err)
continue
else:
assert False, \
'some error occurred: {e}'.format(e=err)
cnt = 0
try:
read_data = json.load(temp_file)
except ValueError:
temp_file.seek(0)
assert False, "{op} output was not valid JSON:\n{filedata}".format(op, temp_file.readlines())

if sop == 'existing':
assert key in read_data, "key '{k}' not found in list/dump output".format(k=key)
if op == 'dump':
cnt = len(read_data[key])
assert cnt == CONFIG_EXISTING[key], \
"wrong size from list for key '{k}': {sz}, expected {es}".format(
k=key, sz=cnt, es=CONFIG_EXISTING[key])
elif sop == 'enoent':
assert key not in read_data, "key '{k}' found in list/dump output".format(k=key)
destroy_tmp_file(file_path)
continue
else:
assert False, 'unknown op {o}'.format(o=op)

Expand Down
21 changes: 21 additions & 0 deletions src/mon/ConfigKeyService.cc
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,21 @@ void ConfigKeyService::store_list(stringstream &ss)
f.flush(ss);
}

void ConfigKeyService::store_dump(stringstream &ss)
{
KeyValueDB::Iterator iter =
mon->store->get_iterator(STORE_PREFIX);

JSONFormatter f(true);
f.open_object_section("config-key store");

while (iter->valid()) {
f.dump_string(iter->key().c_str(), iter->value().to_str());
iter->next();
}
f.close_section();
f.flush(ss);
}

bool ConfigKeyService::service_dispatch(MonOpRequestRef op)
{
Expand Down Expand Up @@ -187,6 +202,12 @@ bool ConfigKeyService::service_dispatch(MonOpRequestRef op)
store_list(tmp_ss);
rdata.append(tmp_ss);
ret = 0;

} else if (prefix == "config-key dump") {
stringstream tmp_ss;
store_dump(tmp_ss);
rdata.append(tmp_ss);
ret = 0;
}

out:
Expand Down
1 change: 1 addition & 0 deletions src/mon/ConfigKeyService.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class ConfigKeyService : public QuorumService
void store_put(const string &key, bufferlist &bl, Context *cb = NULL);
void store_delete(const string &key, Context *cb = NULL);
void store_list(stringstream &ss);
void store_dump(stringstream &ss);
bool store_exists(const string &key);

static const string STORE_PREFIX;
Expand Down
1 change: 1 addition & 0 deletions src/mon/MonCommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -824,6 +824,7 @@ COMMAND("config-key exists " \
"name=key,type=CephString", \
"check for <key>'s existence", "config-key", "r", "cli,rest")
COMMAND("config-key list ", "list keys", "config-key", "r", "cli,rest")
COMMAND("config-key dump", "dump keys and values", "config-key", "r", "cli,rest")


/*
Expand Down
3 changes: 3 additions & 0 deletions src/test/pybind/test_ceph_argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -1178,6 +1178,9 @@ def test_del(self):
def test_exists(self):
self.check_1_string_arg('config-key', 'exists')

def test_dump(self):
self.check_no_arg('config-key', 'dump')

def test_list(self):
self.check_no_arg('config-key', 'list')
# Local Variables:
Expand Down

0 comments on commit 3a68017

Please sign in to comment.