ctdb-tools: Add logging config options to config tool
[samba.git] / ctdb / common / conf_tool.c
1 /*
2    Config options tool
3
4    Copyright (C) Amitay Isaacs  2018
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "replace.h"
21
22 #include <talloc.h>
23
24 #include "lib/util/debug.h"
25
26 #include "common/logging.h"
27 #include "common/cmdline.h"
28 #include "common/conf.h"
29 #include "common/path.h"
30
31 #include "common/logging_conf.h"
32
33 #include "common/conf_tool.h"
34
35 struct conf_tool_context {
36         struct cmdline_context *cmdline;
37         const char *conf_file;
38         struct conf_context *conf;
39 };
40
41 static int conf_tool_dump(TALLOC_CTX *mem_ctx,
42                           int argc,
43                           const char **argv,
44                           void *private_data)
45 {
46         struct conf_tool_context *ctx = talloc_get_type_abort(
47                 private_data, struct conf_tool_context);
48         int ret;
49
50         if (argc != 0) {
51                 cmdline_usage(ctx->cmdline, "dump");
52                 return EINVAL;
53         }
54
55         ret = conf_load(ctx->conf, ctx->conf_file, true);
56         if (ret != 0 && ret != ENOENT) {
57                 D_ERR("Failed to load config file %s\n", ctx->conf_file);
58                 return ret;
59         }
60
61         conf_dump(ctx->conf, stdout);
62         return 0;
63 }
64
65 static int conf_tool_get(TALLOC_CTX *mem_ctx,
66                          int argc,
67                          const char **argv,
68                          void *private_data)
69 {
70         struct conf_tool_context *ctx = talloc_get_type_abort(
71                 private_data, struct conf_tool_context);
72         const char *section, *option;
73         enum conf_type type;
74         int ret;
75         bool ok;
76         const char *s_val = NULL;
77         int i_val;
78         bool b_val;
79
80         if (argc != 2) {
81                 cmdline_usage(ctx->cmdline, "get");
82                 return EINVAL;
83         }
84
85         section = argv[0];
86         option = argv[1];
87
88         ok = conf_query(ctx->conf, section, option, &type);
89         if (!ok) {
90                 D_ERR("Configuration option [%s] -> \"%s\" not defined\n",
91                       section, option);
92                 return ENOENT;
93         }
94
95         ret = conf_load(ctx->conf, ctx->conf_file, true);
96         if (ret != 0 && ret != ENOENT) {
97                 D_ERR("Failed to load config file %s\n", ctx->conf_file);
98                 return ret;
99         }
100
101         switch (type) {
102         case CONF_STRING:
103                 ret = conf_get_string(ctx->conf,
104                                       section,
105                                       option,
106                                       &s_val,
107                                       NULL);
108                 break;
109
110         case CONF_INTEGER:
111                 ret = conf_get_integer(ctx->conf,
112                                        section,
113                                        option,
114                                        &i_val,
115                                        NULL);
116                 break;
117
118         case CONF_BOOLEAN:
119                 ret = conf_get_boolean(ctx->conf,
120                                        section,
121                                        option,
122                                        &b_val,
123                                        NULL);
124                 break;
125
126         default:
127                 D_ERR("Unknown configuration option type\n");
128                 return EINVAL;
129         }
130
131         if (ret != 0) {
132                 D_ERR("Failed to get configuration option value\n");
133                 return ret;
134         }
135
136         switch (type) {
137         case CONF_STRING:
138                 printf("%s\n", s_val == NULL ? "" : s_val);
139                 break;
140
141         case CONF_INTEGER:
142                 printf("%d\n", i_val);
143                 break;
144
145         case CONF_BOOLEAN:
146                 printf("%s\n", b_val ? "true" : "false");
147                 break;
148         }
149
150         return 0;
151 }
152
153 static int conf_tool_validate(TALLOC_CTX *mem_ctx,
154                               int argc,
155                               const char **argv,
156                               void *private_data)
157 {
158         struct conf_tool_context *ctx = talloc_get_type_abort(
159                 private_data, struct conf_tool_context);
160         int ret;
161
162         if (argc != 0) {
163                 cmdline_usage(ctx->cmdline, "validate");
164                 return EINVAL;
165         }
166
167         ret = conf_load(ctx->conf, ctx->conf_file, false);
168         if (ret != 0) {
169                 D_ERR("Failed to load config file %s\n", ctx->conf_file);
170                 return ret;
171         }
172
173         return 0;
174 }
175
176 struct cmdline_command conf_commands[] = {
177         { "dump", conf_tool_dump,
178                 "Dump configuration", NULL },
179         { "get", conf_tool_get,
180                 "Get a config value", "<section> <key>" },
181         { "validate", conf_tool_validate,
182                 "Validate configuration file", NULL },
183         CMDLINE_TABLEEND
184 };
185
186 int conf_tool_init(TALLOC_CTX *mem_ctx,
187                    const char *prog,
188                    struct poptOption *options,
189                    int argc,
190                    const char **argv,
191                    bool parse_options,
192                    struct conf_tool_context **result)
193 {
194         struct conf_tool_context *ctx;
195         int ret;
196
197         ctx = talloc_zero(mem_ctx, struct conf_tool_context);
198         if (ctx == NULL) {
199                 D_ERR("Memory allocation error\n");
200                 return ENOMEM;
201         }
202
203         ret = cmdline_init(ctx, prog, options, conf_commands, &ctx->cmdline);
204         if (ret != 0) {
205                 D_ERR("Failed to initialize cmdline, ret=%d\n", ret);
206                 talloc_free(ctx);
207                 return ret;
208         }
209
210         ret = cmdline_parse(ctx->cmdline, argc, argv, parse_options);
211         if (ret != 0) {
212                 cmdline_usage(ctx->cmdline, NULL);
213                 talloc_free(ctx);
214                 return ret;
215         }
216
217         *result = ctx;
218         return 0;
219 }
220
221 int conf_tool_run(struct conf_tool_context *ctx, int *result)
222 {
223         int ret;
224
225         ctx->conf_file = path_config(ctx);
226         if (ctx->conf_file == NULL) {
227                 D_ERR("Memory allocation error\n");
228                 return ENOMEM;
229         }
230
231         ret = conf_init(ctx, &ctx->conf);
232         if (ret != 0) {
233                 D_ERR("Failed to initialize config\n");
234                 return ret;
235         }
236
237         /* Call functions to initialize config sections/variables */
238         logging_conf_init(ctx->conf, NULL);
239
240         if (! conf_valid(ctx->conf)) {
241                 D_ERR("Failed to define configuration options\n");
242                 return EINVAL;
243         }
244
245         ret = cmdline_run(ctx->cmdline, ctx, result);
246         return ret;
247 }
248
249 #ifdef CTDB_CONF_TOOL
250
251 static struct {
252         const char *debug;
253 } conf_data = {
254         .debug = "ERROR",
255 };
256
257 struct poptOption conf_options[] = {
258         POPT_AUTOHELP
259         { "debug", 'd', POPT_ARG_STRING, &conf_data.debug, 0,
260                 "debug level", "ERROR|WARNING|NOTICE|INFO|DEBUG" },
261         POPT_TABLEEND
262 };
263
264 int main(int argc, const char **argv)
265 {
266         TALLOC_CTX *mem_ctx;
267         struct conf_tool_context *ctx;
268         int ret, result;
269         bool ok;
270
271         mem_ctx = talloc_new(NULL);
272         if (mem_ctx == NULL) {
273                 fprintf(stderr, "Memory allocation error\n");
274                 exit(1);
275         }
276
277         ret = conf_tool_init(mem_ctx,
278                              "ctdb-config",
279                              conf_options,
280                              argc,
281                              argv,
282                              true,
283                              &ctx);
284         if (ret != 0) {
285                 talloc_free(mem_ctx);
286                 exit(1);
287         }
288
289         setup_logging("ctdb-config", DEBUG_STDERR);
290         ok = debug_level_parse(conf_data.debug, &DEBUGLEVEL);
291         if (!ok) {
292                 DEBUGLEVEL = DEBUG_ERR;
293         }
294
295         ret = conf_tool_run(ctx, &result);
296         if (ret != 0) {
297                 result = 1;
298         }
299
300         talloc_free(mem_ctx);
301         exit(result);
302 }
303
304 #endif /* CTDB_CONF_TOOL */