summaryrefslogtreecommitdiffstats
path: root/src/tools/ceph_conf.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/ceph_conf.cc')
-rw-r--r--src/tools/ceph_conf.cc275
1 files changed, 275 insertions, 0 deletions
diff --git a/src/tools/ceph_conf.cc b/src/tools/ceph_conf.cc
new file mode 100644
index 000000000..d26cbb039
--- /dev/null
+++ b/src/tools/ceph_conf.cc
@@ -0,0 +1,275 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2010 Dreamhost
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation. See file COPYING.
+ *
+ */
+
+#include <iomanip>
+#include <string>
+
+#include "common/ceph_argparse.h"
+#include "global/global_init.h"
+#include "mon/AuthMonitor.h"
+#include "common/Formatter.h"
+
+using std::deque;
+using std::string;
+
+static void usage(std::ostream& out)
+{
+ // TODO: add generic_usage once cerr/derr issues are resolved
+ out << R"(Ceph configuration query tool
+
+USAGE
+ceph-conf <flags> <action>
+
+ACTIONS
+ -L|--list-all-sections List all sections
+ -l|--list-sections <prefix> List sections with the given prefix
+ --filter-key <key> Filter section list to only include sections
+ with given key defined.
+ --filter-key-value <key>=<val> Filter section list to only include sections
+ with given key/value pair.
+ --lookup <key> Print a configuration setting to stdout.
+ Returns 0 (success) if the configuration setting is
+ found; 1 otherwise.
+ -r|--resolve-search search for the first file that exists and
+ can be opened in the resulted comma
+ delimited search list.
+ -D|--dump-all dump all variables.
+ --show-config-value <key> Print the corresponding ceph.conf value
+ that matches the specified key. Also searches
+ global defaults.
+
+FLAGS
+ --name name Set type.id
+ [-s <section>] Add to list of sections to search
+ [--format plain|json|json-pretty]
+ dump variables in plain text, json or pretty
+ json
+ [--pid <pid>] Override the $pid when expanding options
+
+If there is no action given, the action will default to --lookup.
+
+EXAMPLES
+$ ceph-conf --name mon.0 -c /etc/ceph/ceph.conf 'mon addr'
+Find out what the value of 'mon addr' is for monitor 0.
+
+$ ceph-conf -l mon
+List sections beginning with 'mon'.
+
+RETURN CODE
+Return code will be 0 on success; error code otherwise.
+)";
+}
+
+static int list_sections(const std::string &prefix,
+ const std::list<string>& filter_key,
+ const std::map<string,string>& filter_key_value)
+{
+ std::vector <std::string> sections;
+ int ret = g_conf().get_all_sections(sections);
+ if (ret)
+ return 2;
+ for (std::vector<std::string>::const_iterator p = sections.begin();
+ p != sections.end(); ++p) {
+ if (strncmp(prefix.c_str(), p->c_str(), prefix.size()))
+ continue;
+
+ std::vector<std::string> sec;
+ sec.push_back(*p);
+
+ int r = 0;
+ for (std::list<string>::const_iterator q = filter_key.begin(); q != filter_key.end(); ++q) {
+ string v;
+ r = g_conf().get_val_from_conf_file(sec, q->c_str(), v, false);
+ if (r < 0)
+ break;
+ }
+ if (r < 0)
+ continue;
+
+ for (std::map<string,string>::const_iterator q = filter_key_value.begin();
+ q != filter_key_value.end();
+ ++q) {
+ string v;
+ r = g_conf().get_val_from_conf_file(sec, q->first.c_str(), v, false);
+ if (r < 0 || v != q->second) {
+ r = -1;
+ break;
+ }
+ }
+ if (r < 0)
+ continue;
+
+ cout << *p << std::endl;
+ }
+ return 0;
+}
+
+static int lookup(const std::deque<std::string> &sections,
+ const std::string &key, bool resolve_search)
+{
+ std::vector<std::string> my_sections{sections.begin(), sections.end()};
+ for (auto& section : g_conf().get_my_sections()) {
+ my_sections.push_back(section);
+ }
+ std::string val;
+ int ret = g_conf().get_val_from_conf_file(my_sections, key.c_str(), val, true);
+ if (ret == -ENOENT)
+ return 1;
+ else if (ret == 0) {
+ if (resolve_search) {
+ string result;
+ ret = ceph_resolve_file_search(val, result);
+ if (!ret)
+ puts(result.c_str());
+ }
+ else {
+ puts(val.c_str());
+ }
+ return 0;
+ }
+ else {
+ cerr << "error looking up '" << key << "': error " << ret << std::endl;
+ return 2;
+ }
+}
+
+static int dump_all(const string& format)
+{
+ if (format == "" || format == "plain") {
+ g_conf().show_config(std::cout);
+ return 0;
+ } else {
+ unique_ptr<Formatter> f(Formatter::create(format));
+ if (f) {
+ f->open_object_section("ceph-conf");
+ g_conf().show_config(f.get());
+ f->close_section();
+ f->flush(std::cout);
+ return 0;
+ }
+ cerr << "format '" << format << "' not recognized." << std::endl;
+ usage(cerr);
+ return 1;
+ }
+}
+
+static void maybe_override_pid(vector<const char*>& args)
+{
+ for (auto i = args.begin(); i != args.end(); ++i) {
+ string val;
+ if (ceph_argparse_witharg(args, i, &val, "--pid", (char*)NULL)) {
+ setenv("PID", val.c_str(), 1);
+ break;
+ }
+ }
+}
+
+int main(int argc, const char **argv)
+{
+ vector<const char*> args;
+ deque<std::string> sections;
+ bool resolve_search = false;
+ std::string action;
+ std::string lookup_key;
+ std::string section_list_prefix;
+ std::list<string> filter_key;
+ std::map<string,string> filter_key_value;
+ std::string dump_format;
+
+ argv_to_vec(argc, argv, args);
+
+ auto orig_args = args;
+ auto cct = [&args] {
+ // override the PID before options are expanded
+ maybe_override_pid(args);
+ std::map<std::string,std::string> defaults = {{"log_to_file", "false"}};
+ return global_init(&defaults, args, CEPH_ENTITY_TYPE_CLIENT,
+ CODE_ENVIRONMENT_DAEMON,
+ CINIT_FLAG_NO_DAEMON_ACTIONS |
+ CINIT_FLAG_NO_MON_CONFIG);
+ }();
+
+ // do not common_init_finish(); do not start threads; do not do any of thing
+ // wonky things the daemon whose conf we are examining would do (like initialize
+ // the admin socket).
+ //common_init_finish(g_ceph_context);
+
+ std::string val;
+ for (std::vector<const char*>::iterator i = args.begin(); i != args.end(); ) {
+ if (ceph_argparse_double_dash(args, i)) {
+ break;
+ } else if (ceph_argparse_witharg(args, i, &val, "-s", "--section", (char*)NULL)) {
+ sections.push_back(val);
+ } else if (ceph_argparse_flag(args, i, "-r", "--resolve_search", (char*)NULL)) {
+ resolve_search = true;
+ } else if (ceph_argparse_flag(args, i, "-h", "--help", (char*)NULL)) {
+ action = "help";
+ } else if (ceph_argparse_witharg(args, i, &val, "--lookup", (char*)NULL)) {
+ action = "lookup";
+ lookup_key = val;
+ } else if (ceph_argparse_flag(args, i, "-L", "--list_all_sections", (char*)NULL)) {
+ action = "list-sections";
+ section_list_prefix = "";
+ } else if (ceph_argparse_witharg(args, i, &val, "-l", "--list_sections", (char*)NULL)) {
+ action = "list-sections";
+ section_list_prefix = val;
+ } else if (ceph_argparse_witharg(args, i, &val, "--filter_key", (char*)NULL)) {
+ filter_key.push_back(val);
+ } else if (ceph_argparse_witharg(args, i, &val, "--filter_key_value", (char*)NULL)) {
+ size_t pos = val.find_first_of('=');
+ if (pos == string::npos) {
+ cerr << "expecting argument like 'key=value' for --filter-key-value (not '" << val << "')" << std::endl;
+ usage(cerr);
+ return EXIT_FAILURE;
+ }
+ string key(val, 0, pos);
+ string value(val, pos+1);
+ filter_key_value[key] = value;
+ } else if (ceph_argparse_flag(args, i, "-D", "--dump_all", (char*)NULL)) {
+ action = "dumpall";
+ } else if (ceph_argparse_witharg(args, i, &val, "--format", (char*)NULL)) {
+ dump_format = val;
+ } else {
+ if (((action == "lookup") || (action == "")) && (lookup_key.empty())) {
+ action = "lookup";
+ lookup_key = *i++;
+ } else {
+ cerr << "unable to parse option: '" << *i << "'" << std::endl;
+ cerr << "args:";
+ for (auto arg : orig_args) {
+ cerr << " " << quoted(arg);
+ }
+ cerr << std::endl;
+ usage(cerr);
+ return EXIT_FAILURE;
+ }
+ }
+ }
+
+ cct->_log->flush();
+ if (action == "help") {
+ usage(cout);
+ return EXIT_SUCCESS;
+ } else if (action == "list-sections") {
+ return list_sections(section_list_prefix, filter_key, filter_key_value);
+ } else if (action == "lookup") {
+ return lookup(sections, lookup_key, resolve_search);
+ } else if (action == "dumpall") {
+ return dump_all(dump_format);
+ } else {
+ cerr << "You must give an action, such as --lookup or --list-all-sections." << std::endl;
+ cerr << "Pass --help for more help." << std::endl;
+ return EXIT_FAILURE;
+ }
+}