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