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