1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2004-2010 Dreamhost
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.
18 #include "common/ceph_argparse.h"
19 #include "global/global_init.h"
20 #include "mon/AuthMonitor.h"
21 #include "common/Formatter.h"
25 using std::unique_ptr
;
30 static void usage(std::ostream
& out
)
32 // TODO: add generic_usage once cerr/derr issues are resolved
33 out
<< R
"(Ceph configuration query tool
36 ceph-conf <flags> <action>
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
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
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
62 [--pid <pid>] Override the $pid when expanding options
64 If there is no action given, the action will default to --lookup.
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.
71 List sections beginning with 'mon'.
74 Return code will be 0 on success; error code otherwise.
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
)
82 std::vector
<std::string
> sections
;
83 int ret
= g_conf().get_all_sections(sections
);
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()))
91 std::vector
<std::string
> sec
;
95 for (std::list
<string
>::const_iterator q
= filter_key
.begin(); q
!= filter_key
.end(); ++q
) {
97 r
= g_conf().get_val_from_conf_file(sec
, q
->c_str(), v
, false);
104 for (std::map
<string
,string
>::const_iterator q
= filter_key_value
.begin();
105 q
!= filter_key_value
.end();
108 r
= g_conf().get_val_from_conf_file(sec
, q
->first
.c_str(), v
, false);
109 if (r
< 0 || v
!= q
->second
) {
117 cout
<< *p
<< std::endl
;
122 static int lookup(const std::deque
<std::string
> §ions
,
123 const std::string
&key
, bool resolve_search
)
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
);
130 int ret
= g_conf().get_val_from_conf_file(my_sections
, key
.c_str(), val
, true);
134 if (resolve_search
) {
136 ret
= ceph_resolve_file_search(val
, result
);
138 puts(result
.c_str());
146 cerr
<< "error looking up '" << key
<< "': error " << ret
<< std::endl
;
151 static int dump_all(const string
& format
)
153 if (format
== "" || format
== "plain") {
154 g_conf().show_config(std::cout
);
157 unique_ptr
<Formatter
> f(Formatter::create(format
));
159 f
->open_object_section("ceph-conf");
160 g_conf().show_config(f
.get());
165 cerr
<< "format '" << format
<< "' not recognized." << std::endl
;
171 static void maybe_override_pid(vector
<const char*>& args
)
173 for (auto i
= args
.begin(); i
!= args
.end(); ++i
) {
175 if (ceph_argparse_witharg(args
, i
, &val
, "--pid", (char*)NULL
)) {
176 setenv("PID", val
.c_str(), 1);
182 int main(int argc
, const char **argv
)
184 deque
<std::string
> sections
;
185 bool resolve_search
= false;
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
;
191 std::string dump_format
;
193 auto args
= argv_to_vec(argc
, argv
);
195 auto orig_args
= args
;
197 // override the PID before options are expanded
198 maybe_override_pid(args
);
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
);
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);
212 for (std::vector
<const char*>::iterator i
= args
.begin(); i
!= args
.end(); ) {
213 if (ceph_argparse_double_dash(args
, i
)) {
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
)) {
221 } else if (ceph_argparse_witharg(args
, i
, &val
, "--lookup", (char*)NULL
)) {
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
;
239 string
key(val
, 0, pos
);
240 string
value(val
, pos
+1);
241 filter_key_value
[key
] = value
;
242 } else if (ceph_argparse_flag(args
, i
, "-D", "--dump_all", (char*)NULL
)) {
244 } else if (ceph_argparse_witharg(args
, i
, &val
, "--format", (char*)NULL
)) {
247 if (((action
== "lookup") || (action
== "")) && (lookup_key
.empty())) {
251 cerr
<< "unable to parse option: '" << *i
<< "'" << std::endl
;
253 for (auto arg
: orig_args
) {
254 cerr
<< " " << std::quoted(arg
);
264 if (action
== "help") {
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
);
271 } else if (action
== "dumpall") {
272 return dump_all(dump_format
);
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
;