Skip to content

Commit

Permalink
Merge remote-tracking branch 'gh/wip-tell-unified' into next
Browse files Browse the repository at this point in the history
Reviewed-by: Sage Weil <[email protected]>
  • Loading branch information
Sage Weil committed Jul 26, 2013
2 parents 6ac8aed + aa00ace commit 0757c60
Show file tree
Hide file tree
Showing 25 changed files with 805 additions and 530 deletions.
134 changes: 75 additions & 59 deletions src/ceph.in
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,6 @@ def parse_cmdargs(args=None, target=''):

parser.add_argument('-h', '--help', help='request mon help',
action='store_true')
parser.add_argument('--help-all', help='request help for all daemons',
action='store_true')

parser.add_argument('-c', '--conf', dest='cephconf',
help='ceph configuration file')
Expand Down Expand Up @@ -150,14 +148,16 @@ def parse_cmdargs(args=None, target=''):

return parser, parsed_args, extras

def do_help(parser, args, help_all = False):
def do_help(parser, args):
"""
Print basic parser help
If the cluster is available:
get and print monitor help;
if help_all, print help for daemon commands as well
If the cluster is available, get and print monitor help
"""

def help_for_sigs(sigs, partial=None):
sys.stdout.write(format_help(parse_json_funcsigs(sigs, 'cli'),
partial=partial))

def help_for_target(target, partial=None):
ret, outbuf, outs = json_command(cluster_handle, target=target,
prefix='get_command_descriptions',
Expand All @@ -167,40 +167,19 @@ def do_help(parser, args, help_all = False):
"couldn't get command descriptions for {0}: {1}".\
format(target, outs)
else:
sys.stdout.write(format_help(parse_json_funcsigs(outbuf, 'cli'),
partial))
help_for_sigs(outbuf, partial)

parser.print_help()
print '\n'
if (cluster_handle):
help_for_target(target=('mon', ''), partial=' '.join(args))

if help_all and cluster_handle:
# try/except in case there are no daemons of that type
try:
firstosd = osdids()[0]
print '\nOSD.{0} tell commands and pg pgid commands:\n\n'.\
format(firstosd)
help_for_target(target=('osd', osdids()[0]))

print '\nOSD daemon commands:\n\n'
sys.stdout.write(format_help(parse_json_funcsigs(admin_socket(ceph_conf('admin_socket', 'osd.' + firstosd), ['get_command_descriptions']), 'cli')))
except:
pass
def hdr(s):
print '\n', s, '\n', '=' * len(s)

try:
firstmon = monids()[0]
print '\nmon.{0} daemon commands:\n\n'.format(firstmon)
sys.stdout.write(format_help(parse_json_funcsigs(admin_socket(ceph_conf('admin_socket', 'mon.' + firstmon), ['get_command_descriptions']), 'cli')))
except:
pass
hdr('Monitor commands:')
partial = ' '.join(args)
parser.print_help()
print '\n'

try:
firstmds = mdsids()[0]
print '\nmds.{0} daemon commands:\n\n'.format(firstmds)
sys.stdout.write(format_help(parse_json_funcsigs(admin_socket(ceph_conf('admin_socket', 'mds.' + firstmds), ['get_command_descriptions']), 'cli')))
except:
pass
if (cluster_handle):
help_for_target(target=('mon', ''), partial=partial)

return 0

Expand Down Expand Up @@ -285,26 +264,57 @@ def format_help(cmddict, partial=None):

return fullusage

def admin_socket(asok_path, cmd):
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
def admin_socket(asok_path, cmd, format=''):
"""
Send a daemon (--admin-daemon) command 'cmd'. asok_path is the
path to the admin socket; cmd is a list of strings; format may be
set to one of the formatted forms to get output in that form
(daemon commands don't support 'plain' output).
"""

def do_sockio(path, cmd):
""" helper: do all the actual low-level stream I/O """
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect(path)
try:
sock.sendall(cmd + '\0')
len_str = sock.recv(4)
if len(len_str) < 4:
raise RuntimeError("no data returned from admin socket")
l, = struct.unpack(">I", len_str)
ret = ''

got = 0
while got < l:
bit = sock.recv(l - got)
ret += bit
got += len(bit)

except Exception as e:
raise RuntimeError('exception: ' + str(e))
return ret

try:
sock.connect(asok_path)
sock.sendall(' '.join(cmd) + '\0')
cmd_json = do_sockio(asok_path,
json.dumps({"prefix":"get_command_descriptions"}))
except Exception as e:
raise RuntimeError('exception getting command descriptions: ' + str(e))

if cmd == 'get_command_descriptions':
return cmd_json

len_str = sock.recv(4)
if len(len_str) < 4:
raise RuntimeError("no data returned from admin socket")
l, = struct.unpack(">I", len_str)
ret = ''
sigdict = parse_json_funcsigs(cmd_json, 'cli')
valid_dict = validate_command(sigdict, cmd)
if not valid_dict:
return -errno.EINVAL

got = 0
while got < l:
bit = sock.recv(l - got)
ret += bit
got += len(bit)
if format:
valid_dict['format'] = format

try:
ret = do_sockio(asok_path, json.dumps(valid_dict))
except Exception as e:
raise RuntimeError('exception: {0}'.format(e))
raise RuntimeError('exception: ' + str(e))

return ret

Expand Down Expand Up @@ -344,10 +354,11 @@ def new_style_command(parsed_args, cmdargs, target, sigdict, inbuf, verbose):
if not got_command:
if cmdargs:
# Validate input args against list of sigs
valid_dict = validate_command(parsed_args, sigdict, cmdargs,
verbose)
valid_dict = validate_command(sigdict, cmdargs, verbose)
if valid_dict:
got_command = True
if parsed_args.output_format:
valid_dict['format'] = parsed_args.output_format
else:
return -errno.EINVAL, '', 'invalid command'
else:
Expand All @@ -360,8 +371,10 @@ def new_style_command(parsed_args, cmdargs, target, sigdict, inbuf, verbose):
return 0, '', ''
cmdargs = parse_cmdargs(interactive_input.split())[2]
target = find_cmd_target(cmdargs)
valid_dict = validate_command(parsed_args, sigdict, cmdargs)
valid_dict = validate_command(sigdict, cmdargs, verbose)
if valid_dict:
if parsed_args.output_format:
valid_dict['format'] = parsed_args.output_format
if verbose:
print >> sys.stderr, "Submitting command ", valid_dict
ret, outbuf, outs = json_command(cluster_handle,
Expand Down Expand Up @@ -470,9 +483,12 @@ def main():
conffile = parsed_args.cephconf
# For now, --admin-daemon is handled as usual. Try it
# first in case we can't connect() to the cluster

format = parsed_args.output_format

if parsed_args.admin_socket:
try:
print admin_socket(parsed_args.admin_socket, childargs)
print admin_socket(parsed_args.admin_socket, childargs, format)
except Exception as e:
print >> sys.stderr, 'admin_socket: {0}'.format(e)
return 0
Expand All @@ -481,15 +497,15 @@ def main():
if len(childargs) > 2:
if childargs[1].find('/') >= 0:
try:
print admin_socket(childargs[1], childargs[2:])
print admin_socket(childargs[1], childargs[2:], format)
except Exception as e:
print >> sys.stderr, 'admin_socket: {0}'.format(e)
return 0
else:
# try resolve daemon name
path = ceph_conf('admin_socket', childargs[1])
try:
print admin_socket(path, childargs[2:])
print admin_socket(path, childargs[2:], format)
except Exception as e:
print >> sys.stderr, 'admin_socket: {0}'.format(e)
return 0
Expand Down Expand Up @@ -544,8 +560,8 @@ def main():
format(e.__class__.__name__)
return 1

if parsed_args.help or parsed_args.help_all:
return do_help(parser, childargs, parsed_args.help_all)
if parsed_args.help:
return do_help(parser, childargs)

# implement -w/--watch_*
# This is ugly, but Namespace() isn't quite rich enough.
Expand Down
14 changes: 8 additions & 6 deletions src/client/Client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -102,22 +102,24 @@ Client::CommandHook::CommandHook(Client *client) :
{
}

bool Client::CommandHook::call(std::string command, std::string args, bufferlist& out)
bool Client::CommandHook::call(std::string command, std::string args,
std::string format, bufferlist& out)
{
stringstream ss;
JSONFormatter formatter(true);
Formatter *f = new_formatter(format);
m_client->client_lock.Lock();
if (command == "mds_requests")
m_client->dump_mds_requests(&formatter);
m_client->dump_mds_requests(f);
else if (command == "mds_sessions")
m_client->dump_mds_sessions(&formatter);
m_client->dump_mds_sessions(f);
else if (command == "dump_cache")
m_client->dump_cache(&formatter);
m_client->dump_cache(f);
else
assert(0 == "bad command registered");
m_client->client_lock.Unlock();
formatter.flush(ss);
f->flush(ss);
out.append(ss);
delete f;
return true;
}

Expand Down
3 changes: 2 additions & 1 deletion src/client/Client.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,8 @@ class Client : public Dispatcher {
Client *m_client;
public:
CommandHook(Client *client);
bool call(std::string command, std::string args, bufferlist& out);
bool call(std::string command, std::string args, std::string format,
bufferlist& out);
};
CommandHook m_command_hook;

Expand Down
14 changes: 9 additions & 5 deletions src/common/Formatter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,19 @@ Formatter::~Formatter()
}

Formatter *
new_formatter(const std::string &type)
new_formatter(const std::string type)
{
if (type == "json")
std::string mytype = type;
if (mytype == "")
mytype = "json-pretty";

if (mytype == "json")
return new JSONFormatter(false);
else if (type == "json-pretty")
else if (mytype == "json-pretty")
return new JSONFormatter(true);
else if (type == "xml")
else if (mytype == "xml")
return new XMLFormatter(false);
else if (type == "xml-pretty")
else if (mytype == "xml-pretty")
return new XMLFormatter(true);
else
return (Formatter *)NULL;
Expand Down
2 changes: 1 addition & 1 deletion src/common/Formatter.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class Formatter {
}
};

Formatter *new_formatter(const std::string &type);
Formatter *new_formatter(const std::string type);

class JSONFormatter : public Formatter {
public:
Expand Down
32 changes: 23 additions & 9 deletions src/common/admin_socket.cc
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,18 @@ bool AdminSocket::do_accept()

bool rval = false;

map<string, cmd_vartype> cmdmap;
string format;
vector<string> cmdvec;
stringstream errss;
cmdvec.push_back(cmd);
if (!cmdmap_from_json(cmdvec, &cmdmap, errss)) {
ldout(m_cct, 0) << "AdminSocket: " << errss << dendl;
return false;
}
cmd_getval(m_cct, cmdmap, "format", format);
cmd_getval(m_cct, cmdmap, "prefix", c);

string firstword;
if (c.find(" ") == string::npos)
firstword = c;
Expand Down Expand Up @@ -341,7 +353,7 @@ bool AdminSocket::do_accept()
string args;
if (match != c)
args = c.substr(match.length() + 1);
bool success = p->second->call(match, args, out);
bool success = p->second->call(match, args, format, out);
if (!success) {
ldout(m_cct, 0) << "AdminSocket: request '" << match << "' args '" << args
<< "' to " << p->second << " failed" << dendl;
Expand Down Expand Up @@ -406,7 +418,8 @@ int AdminSocket::unregister_command(std::string command)

class VersionHook : public AdminSocketHook {
public:
virtual bool call(std::string command, std::string args, bufferlist& out) {
virtual bool call(std::string command, std::string args, std::string format,
bufferlist& out) {
if (command == "0") {
out.append(CEPH_ADMIN_SOCK_VERSION);
} else {
Expand All @@ -429,18 +442,19 @@ class HelpHook : public AdminSocketHook {
AdminSocket *m_as;
public:
HelpHook(AdminSocket *as) : m_as(as) {}
bool call(string command, string args, bufferlist& out) {
JSONFormatter jf(true);
jf.open_object_section("help");
bool call(string command, string args, string format, bufferlist& out) {
Formatter *f = new_formatter(format);
f->open_object_section("help");
for (map<string,string>::iterator p = m_as->m_help.begin();
p != m_as->m_help.end();
++p) {
jf.dump_string(p->first.c_str(), p->second);
f->dump_string(p->first.c_str(), p->second);
}
jf.close_section();
f->close_section();
ostringstream ss;
jf.flush(ss);
f->flush(ss);
out.append(ss.str());
delete f;
return true;
}
};
Expand All @@ -449,7 +463,7 @@ class GetdescsHook : public AdminSocketHook {
AdminSocket *m_as;
public:
GetdescsHook(AdminSocket *as) : m_as(as) {}
bool call(string command, string args, bufferlist& out) {
bool call(string command, string args, string format, bufferlist& out) {
int cmdnum = 0;
JSONFormatter jf(false);
jf.open_object_section("command_descriptions");
Expand Down
3 changes: 2 additions & 1 deletion src/common/admin_socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ class CephContext;

class AdminSocketHook {
public:
virtual bool call(std::string command, std::string args, bufferlist& out) = 0;
virtual bool call(std::string command, std::string args, std::string format,
bufferlist& out) = 0;
virtual ~AdminSocketHook() {};
};

Expand Down
Loading

0 comments on commit 0757c60

Please sign in to comment.