]>
Commit | Line | Data |
---|---|---|
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 | |
23 | using std::deque; | |
24 | using std::string; | |
20effc67 TL |
25 | using std::unique_ptr; |
26 | using std::cerr; | |
27 | using std::cout; | |
28 | using std::vector; | |
7c673cae | 29 | |
9f95a23c | 30 | static 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 | ||
35 | USAGE | |
36 | ceph-conf <flags> <action> | |
37 | ||
38 | ACTIONS | |
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 | ||
56 | FLAGS | |
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 | |
64 | If there is no action given, the action will default to --lookup. | |
65 | ||
66 | EXAMPLES | |
67 | $ ceph-conf --name mon.0 -c /etc/ceph/ceph.conf 'mon addr' | |
68 | Find out what the value of 'mon addr' is for monitor 0. | |
69 | ||
70 | $ ceph-conf -l mon | |
71 | List sections beginning with 'mon'. | |
72 | ||
73 | RETURN CODE | |
74 | Return code will be 0 on success; error code otherwise. | |
75 | )"; | |
7c673cae FG |
76 | } |
77 | ||
78 | static 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 | ||
122 | static int lookup(const std::deque<std::string> §ions, | |
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 |
151 | static 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 |
171 | static 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 |
182 | int 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 | } |