38 #include <boost/algorithm/string.hpp>
39 #include <boost/tokenizer.hpp>
59 COMMAND_COPYFROMLOCAL,
72 int fsbroker::CommandInterpreter::execute_line(
const String &line) {
75 parse_line(line, parse);
82 case COMMAND_COPYFROMLOCAL:
86 case COMMAND_COPYTOLOCAL:
91 cout << (m_client->exists(parse.
args[0]) ?
"true" :
"false") << endl;
95 if (parse.
args.empty())
96 parse.
args.push_back(
"contents");
97 display_help_text(parse.
args[0]);
101 cout << m_client->length(parse.
args[0]) << endl;
105 m_client->mkdirs(parse.
args[0]);
109 m_client->remove(parse.
args[0]);
113 m_client->rmdir(parse.
args[0]);
119 if (!parse.
args.empty()) {
124 m_client->shutdown(flags, 0);
128 m_client->shutdown(flags, &sync_handler);
137 m_client->status(status);
140 status.
get(&code, output);
144 cout <<
" - " << output;
147 return static_cast<int>(code);
158 void fsbroker::CommandInterpreter::ParseResult::clear() {
170 boost::char_separator<char> sep(
" ");
171 boost::tokenizer< boost::char_separator<char> > tokens(line, sep);
172 for (
const string& arg : tokens) {
173 if (command.empty()) {
176 else if (boost::algorithm::starts_with(arg,
"--seek=")) {
177 char *base = (
char *)arg.c_str() + 7;
180 result.
offset = strtoll(base, &end, 10);
181 if (errno != 0 || end == base) {
182 parse_error(command);
187 result.
args.push_back(arg);
193 if (!strcasecmp(command.c_str(),
"copyFromLocal")) {
194 if (result.
args.size() != 2)
195 parse_error(command);
197 result.
command = COMMAND_COPYFROMLOCAL;
199 else if (!strcasecmp(command.c_str(),
"copyToLocal")) {
200 if (result.
args.size() != 2)
201 parse_error(command);
203 result.
command = COMMAND_COPYTOLOCAL;
205 else if (!strcasecmp(command.c_str(),
"exists")) {
206 if (result.
args.size() != 1)
207 parse_error(command);
211 else if (!strcasecmp(command.c_str(),
"help")) {
214 else if (!strcasecmp(command.c_str(),
"length")) {
215 if (result.
args.size() != 1)
216 parse_error(command);
218 result.
command = COMMAND_LENGTH;
220 else if (!strcasecmp(command.c_str(),
"mkdirs")) {
221 if (result.
args.size() != 1)
222 parse_error(command);
226 else if (!strcasecmp(command.c_str(),
"rm")) {
227 if (result.
args.size() != 1)
228 parse_error(command);
230 result.
command = COMMAND_REMOVE;
232 else if (!strcasecmp(command.c_str(),
"rmdir")) {
233 if (result.
args.size() != 1)
234 parse_error(command);
236 result.
command = COMMAND_RMDIR;
238 else if (!strcasecmp(command.c_str(),
"shutdown")) {
239 if (result.
args.empty() ||
240 (result.
args.size() == 1 && !strcasecmp(result.
args[0].c_str(),
"now")))
243 parse_error(command);
245 else if (!strcasecmp(command.c_str(),
"status")) {
246 if (!result.
args.empty())
247 parse_error(command);
253 cout <<
"Unrecognized command - '" << command <<
"'" << endl;
255 HT_FATALF(
"Unrecognized command - '%s'", command.c_str());
263 const char *g_help_text_contents[] = {
264 "copyFromLocal ......... Copy file from local filesystem to brokered filesystem",
265 "copyToLocal ........... Copy file from brokered filesystem to local filesystem",
266 "exists ................ Check for file existence",
267 "length ................ Get length of file",
268 "mkdirs ................ Create directory and missing parent directories",
269 "rm .................... Remove file",
270 "rmdir ................. Remove directory",
271 "shutdown .............. Shutdown file system broker",
272 "status ................ Get status of file system broker",
274 "Statements must be terminated with ';'. For more information on",
275 "a specific statement, type 'help <statement>', where <statement> is from",
276 "the preceeding list.",
280 const char *g_help_text_copyfromlocal[] = {
281 "copyFromLocal [--seek=<offset>] <src> <dst>",
283 " This command copies the local file <src> to the remote file <dst>",
284 " in the brokered file system. If --seek is supplied, then the source",
285 " file is seeked to offset <offset> before starting the copy.",
289 const char *g_help_text_copytolocal[] = {
290 "copyToLocal [--seek=<offset>] <src> <dst>",
292 " This command copies the file <src> from the brokered file system to"
293 " the <dst> file in the local filesystem. If --seek is supplied, then",
294 " the source file is seeked to offset <offset> before starting the copy.",
298 const char *g_help_text_exists[] = {
301 " This command checks for the existence of <file> in the brokered",
302 " filesystem and prints \"true\" if it exists, or \"false\" otherwise.",
306 const char *g_help_text_length[] = {
309 " This command fetches the length of <file> in the brokered filesystem",
310 " and prints it to the console.",
314 const char *g_help_text_mkdirs[] = {
317 " This command creates a directory and all of its missing parents in",
318 " the broked filesystem.",
322 const char *g_help_text_remove[] = {
325 " This command removes the file <file> in the brokered filesystem.",
329 const char *g_help_text_rmdir[] = {
332 " This command recursively removes <dir> from the brokered filesystem",
336 const char *g_help_text_shutdown[] = {
339 " This command sends a shutdown request to the filesystem broker.",
340 " If the 'now' argument is given, the broker will do an unclean",
341 " shutdown by exiting immediately. Otherwise, it will wait for",
342 " all pending requests to complete before shutting down.",
346 const char *g_help_text_status[] = {
349 " This command sends a status request to the filesystem broker, printing",
350 " the status output message to the console and returning the status code.",
351 " The return value of the last command issued to the interpreter will be",
352 " used as the exit status.",
357 void fsbroker::CommandInterpreter::load_help_text() {
358 m_help_text[
"contents"] = g_help_text_contents;
359 m_help_text[
"copyfromlocal"] = g_help_text_copyfromlocal;
360 m_help_text[
"copyToLocal"] = g_help_text_copytolocal;
361 m_help_text[
"exists"] = g_help_text_exists;
362 m_help_text[
"length"] = g_help_text_length;
363 m_help_text[
"mkdirs"] = g_help_text_mkdirs;
364 m_help_text[
"rm"] = g_help_text_remove;
365 m_help_text[
"rmdir"] = g_help_text_rmdir;
366 m_help_text[
"shutdown"] = g_help_text_shutdown;
367 m_help_text[
"status"] = g_help_text_status;
371 void fsbroker::CommandInterpreter::display_help_text(
const std::string &command)
const {
372 string lower(command);
373 boost::algorithm::to_lower(lower);
374 auto iter = m_help_text.find(lower);
375 if (iter != m_help_text.end()) {
376 const char **text = iter->second;
378 for (
size_t i=0; text[i]; i++)
379 cout << text[i] << endl;
383 cout << endl <<
"No help for '" << command <<
"'" << endl << endl;
386 void fsbroker::CommandInterpreter::display_usage(
const std::string &command)
const {
387 string lower(command);
388 boost::algorithm::to_lower(lower);
389 auto iter = m_help_text.find(lower);
391 const char **text = iter->second;
392 cout <<
"Usage: " << text[0] << endl;
395 void fsbroker::CommandInterpreter::parse_error(
const std::string &command)
const {
396 string lower(command);
397 boost::algorithm::to_lower(lower);
398 auto iter = m_help_text.find(lower);
400 const char **text = iter->second;
402 cout <<
"Parse error." << endl;
403 cout <<
"Usage: " << text[0] << endl;
Holds Nagios-style program status information.
std::string String
A String is simply a typedef to std::string.
std::shared_ptr< Event > EventPtr
Smart pointer to Event.
void copy_to_local(ClientPtr &client, const std::string &from, const std::string &to, int64_t offset=0)
bool wait_for_reply(EventPtr &event)
This method is used by a client to synchronize.
Code
Enumeration for status codes.
static const char * code_to_string(Code code)
bool status(ContextPtr &context, Timer &timer, Status &status)
Runs a status check on the master.
Declarations for CommandInterpreter.
Compatibility Macros for C/C++.
Perform immediate shutdown.
#define HT_FATALF(msg,...)
DispatchHandler class used to synchronize with response messages.
void copy_from_local(ClientPtr &client, const std::string &from, const std::string &to, int64_t offset=0)
#define HT_THROWF(_code_, _fmt_,...)
void get(Code *code, std::string &text) const
Gets status code and text.
Declarations of utility functions.
Declarations for HqlHelpText.
Error codes, Exception handling, error logging.