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