]> git.proxmox.com Git - ceph.git/blame - ceph/src/tools/ceph_conf.cc
import quincy beta 17.1.0
[ceph.git] / ceph / src / tools / ceph_conf.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2004-2010 Dreamhost
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
9f95a23c 15#include <iomanip>
7c673cae
FG
16#include <string>
17
18#include "common/ceph_argparse.h"
19#include "global/global_init.h"
20#include "mon/AuthMonitor.h"
b32b8144 21#include "common/Formatter.h"
7c673cae
FG
22
23using std::deque;
24using std::string;
20effc67
TL
25using std::unique_ptr;
26using std::cerr;
27using std::cout;
28using std::vector;
7c673cae 29
9f95a23c 30static void usage(std::ostream& out)
7c673cae
FG
31{
32 // TODO: add generic_usage once cerr/derr issues are resolved
9f95a23c
TL
33 out << R"(Ceph configuration query tool
34
35USAGE
36ceph-conf <flags> <action>
37
38ACTIONS
39 -L|--list-all-sections List all sections
40 -l|--list-sections <prefix> List sections with the given prefix
41 --filter-key <key> Filter section list to only include sections
42 with given key defined.
43 --filter-key-value <key>=<val> Filter section list to only include sections
44 with given key/value pair.
45 --lookup <key> Print a configuration setting to stdout.
46 Returns 0 (success) if the configuration setting is
47 found; 1 otherwise.
48 -r|--resolve-search search for the first file that exists and
49 can be opened in the resulted comma
50 delimited search list.
51 -D|--dump-all dump all variables.
52 --show-config-value <key> Print the corresponding ceph.conf value
53 that matches the specified key. Also searches
54 global defaults.
55
56FLAGS
57 --name name Set type.id
58 [-s <section>] Add to list of sections to search
59 [--format plain|json|json-pretty]
60 dump variables in plain text, json or pretty
61 json
f67539c2 62 [--pid <pid>] Override the $pid when expanding options
9f95a23c
TL
63
64If there is no action given, the action will default to --lookup.
65
66EXAMPLES
67$ ceph-conf --name mon.0 -c /etc/ceph/ceph.conf 'mon addr'
68Find out what the value of 'mon addr' is for monitor 0.
69
70$ ceph-conf -l mon
71List sections beginning with 'mon'.
72
73RETURN CODE
74Return code will be 0 on success; error code otherwise.
75)";
7c673cae
FG
76}
77
78static int list_sections(const std::string &prefix,
79 const std::list<string>& filter_key,
80 const std::map<string,string>& filter_key_value)
81{
82 std::vector <std::string> sections;
11fdf7f2 83 int ret = g_conf().get_all_sections(sections);
7c673cae
FG
84 if (ret)
85 return 2;
86 for (std::vector<std::string>::const_iterator p = sections.begin();
87 p != sections.end(); ++p) {
88 if (strncmp(prefix.c_str(), p->c_str(), prefix.size()))
89 continue;
90
91 std::vector<std::string> sec;
92 sec.push_back(*p);
93
94 int r = 0;
95 for (std::list<string>::const_iterator q = filter_key.begin(); q != filter_key.end(); ++q) {
96 string v;
11fdf7f2 97 r = g_conf().get_val_from_conf_file(sec, q->c_str(), v, false);
7c673cae
FG
98 if (r < 0)
99 break;
100 }
101 if (r < 0)
102 continue;
103
104 for (std::map<string,string>::const_iterator q = filter_key_value.begin();
105 q != filter_key_value.end();
106 ++q) {
107 string v;
11fdf7f2 108 r = g_conf().get_val_from_conf_file(sec, q->first.c_str(), v, false);
7c673cae
FG
109 if (r < 0 || v != q->second) {
110 r = -1;
111 break;
112 }
113 }
114 if (r < 0)
115 continue;
116
117 cout << *p << std::endl;
118 }
119 return 0;
120}
121
122static int lookup(const std::deque<std::string> &sections,
123 const std::string &key, bool resolve_search)
124{
f67539c2
TL
125 std::vector<std::string> my_sections{sections.begin(), sections.end()};
126 for (auto& section : g_conf().get_my_sections()) {
127 my_sections.push_back(section);
7c673cae 128 }
7c673cae 129 std::string val;
11fdf7f2 130 int ret = g_conf().get_val_from_conf_file(my_sections, key.c_str(), val, true);
7c673cae
FG
131 if (ret == -ENOENT)
132 return 1;
133 else if (ret == 0) {
134 if (resolve_search) {
135 string result;
136 ret = ceph_resolve_file_search(val, result);
137 if (!ret)
138 puts(result.c_str());
139 }
140 else {
141 puts(val.c_str());
142 }
143 return 0;
144 }
145 else {
146 cerr << "error looking up '" << key << "': error " << ret << std::endl;
147 return 2;
148 }
149}
150
b32b8144
FG
151static int dump_all(const string& format)
152{
153 if (format == "" || format == "plain") {
11fdf7f2 154 g_conf().show_config(std::cout);
b32b8144
FG
155 return 0;
156 } else {
157 unique_ptr<Formatter> f(Formatter::create(format));
158 if (f) {
159 f->open_object_section("ceph-conf");
11fdf7f2 160 g_conf().show_config(f.get());
b32b8144
FG
161 f->close_section();
162 f->flush(std::cout);
163 return 0;
164 }
165 cerr << "format '" << format << "' not recognized." << std::endl;
9f95a23c 166 usage(cerr);
b32b8144
FG
167 return 1;
168 }
169}
170
f67539c2
TL
171static void maybe_override_pid(vector<const char*>& args)
172{
173 for (auto i = args.begin(); i != args.end(); ++i) {
174 string val;
175 if (ceph_argparse_witharg(args, i, &val, "--pid", (char*)NULL)) {
176 setenv("PID", val.c_str(), 1);
177 break;
178 }
179 }
180}
181
7c673cae
FG
182int main(int argc, const char **argv)
183{
7c673cae
FG
184 deque<std::string> sections;
185 bool resolve_search = false;
186 std::string action;
187 std::string lookup_key;
188 std::string section_list_prefix;
189 std::list<string> filter_key;
190 std::map<string,string> filter_key_value;
b32b8144 191 std::string dump_format;
7c673cae 192
20effc67 193 auto args = argv_to_vec(argc, argv);
f67539c2 194
9f95a23c
TL
195 auto orig_args = args;
196 auto cct = [&args] {
f67539c2
TL
197 // override the PID before options are expanded
198 maybe_override_pid(args);
9f95a23c
TL
199 std::map<std::string,std::string> defaults = {{"log_to_file", "false"}};
200 return global_init(&defaults, args, CEPH_ENTITY_TYPE_CLIENT,
201 CODE_ENVIRONMENT_DAEMON,
202 CINIT_FLAG_NO_DAEMON_ACTIONS |
203 CINIT_FLAG_NO_MON_CONFIG);
204 }();
7c673cae
FG
205
206 // do not common_init_finish(); do not start threads; do not do any of thing
207 // wonky things the daemon whose conf we are examining would do (like initialize
208 // the admin socket).
209 //common_init_finish(g_ceph_context);
210
211 std::string val;
212 for (std::vector<const char*>::iterator i = args.begin(); i != args.end(); ) {
213 if (ceph_argparse_double_dash(args, i)) {
214 break;
215 } else if (ceph_argparse_witharg(args, i, &val, "-s", "--section", (char*)NULL)) {
216 sections.push_back(val);
217 } else if (ceph_argparse_flag(args, i, "-r", "--resolve_search", (char*)NULL)) {
218 resolve_search = true;
219 } else if (ceph_argparse_flag(args, i, "-h", "--help", (char*)NULL)) {
220 action = "help";
221 } else if (ceph_argparse_witharg(args, i, &val, "--lookup", (char*)NULL)) {
222 action = "lookup";
223 lookup_key = val;
224 } else if (ceph_argparse_flag(args, i, "-L", "--list_all_sections", (char*)NULL)) {
225 action = "list-sections";
226 section_list_prefix = "";
227 } else if (ceph_argparse_witharg(args, i, &val, "-l", "--list_sections", (char*)NULL)) {
228 action = "list-sections";
229 section_list_prefix = val;
230 } else if (ceph_argparse_witharg(args, i, &val, "--filter_key", (char*)NULL)) {
231 filter_key.push_back(val);
232 } else if (ceph_argparse_witharg(args, i, &val, "--filter_key_value", (char*)NULL)) {
233 size_t pos = val.find_first_of('=');
234 if (pos == string::npos) {
235 cerr << "expecting argument like 'key=value' for --filter-key-value (not '" << val << "')" << std::endl;
9f95a23c
TL
236 usage(cerr);
237 return EXIT_FAILURE;
7c673cae
FG
238 }
239 string key(val, 0, pos);
240 string value(val, pos+1);
241 filter_key_value[key] = value;
b32b8144
FG
242 } else if (ceph_argparse_flag(args, i, "-D", "--dump_all", (char*)NULL)) {
243 action = "dumpall";
244 } else if (ceph_argparse_witharg(args, i, &val, "--format", (char*)NULL)) {
245 dump_format = val;
7c673cae
FG
246 } else {
247 if (((action == "lookup") || (action == "")) && (lookup_key.empty())) {
248 action = "lookup";
249 lookup_key = *i++;
250 } else {
251 cerr << "unable to parse option: '" << *i << "'" << std::endl;
252 cerr << "args:";
9f95a23c 253 for (auto arg : orig_args) {
20effc67 254 cerr << " " << std::quoted(arg);
7c673cae
FG
255 }
256 cerr << std::endl;
9f95a23c
TL
257 usage(cerr);
258 return EXIT_FAILURE;
7c673cae
FG
259 }
260 }
261 }
262
9f95a23c 263 cct->_log->flush();
7c673cae 264 if (action == "help") {
9f95a23c
TL
265 usage(cout);
266 return EXIT_SUCCESS;
7c673cae
FG
267 } else if (action == "list-sections") {
268 return list_sections(section_list_prefix, filter_key, filter_key_value);
269 } else if (action == "lookup") {
270 return lookup(sections, lookup_key, resolve_search);
b32b8144
FG
271 } else if (action == "dumpall") {
272 return dump_all(dump_format);
7c673cae
FG
273 } else {
274 cerr << "You must give an action, such as --lookup or --list-all-sections." << std::endl;
275 cerr << "Pass --help for more help." << std::endl;
9f95a23c 276 return EXIT_FAILURE;
7c673cae
FG
277 }
278}