diff options
author | Amitay Isaacs <amitay@gmail.com> | 2018-04-27 17:21:00 +1000 |
---|---|---|
committer | Martin Schwenke <martins@samba.org> | 2018-05-12 12:06:28 +0200 |
commit | e96e1defbaf6d524c046b3aea90fe150c0fadcd9 (patch) | |
tree | c05ece32da8c69a851293c5818a1baa01213f75f | |
parent | 702504118f027bd75e959f4d16428758caf9a108 (diff) | |
download | samba-e96e1defbaf6d524c046b3aea90fe150c0fadcd9.tar.gz |
ctdb-common: Add config options tool
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
-rw-r--r-- | ctdb/common/conf_tool.c | 301 | ||||
-rw-r--r-- | ctdb/common/conf_tool.h | 39 | ||||
-rwxr-xr-x | ctdb/tests/cunit/config_test_001.sh | 56 | ||||
-rw-r--r-- | ctdb/wscript | 6 |
4 files changed, 402 insertions, 0 deletions
diff --git a/ctdb/common/conf_tool.c b/ctdb/common/conf_tool.c new file mode 100644 index 00000000000..108cf67b651 --- /dev/null +++ b/ctdb/common/conf_tool.c @@ -0,0 +1,301 @@ +/* + Config options tool + + Copyright (C) Amitay Isaacs 2018 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include "replace.h" + +#include <talloc.h> + +#include "lib/util/debug.h" + +#include "common/logging.h" +#include "common/cmdline.h" +#include "common/conf.h" +#include "common/path.h" + +#include "common/conf_tool.h" + +struct conf_tool_context { + struct cmdline_context *cmdline; + const char *conf_file; + struct conf_context *conf; +}; + +static int conf_tool_dump(TALLOC_CTX *mem_ctx, + int argc, + const char **argv, + void *private_data) +{ + struct conf_tool_context *ctx = talloc_get_type_abort( + private_data, struct conf_tool_context); + int ret; + + if (argc != 0) { + cmdline_usage(ctx->cmdline, "dump"); + return EINVAL; + } + + ret = conf_load(ctx->conf, ctx->conf_file, true); + if (ret != 0 && ret != ENOENT) { + D_ERR("Failed to load config file %s\n", ctx->conf_file); + return ret; + } + + conf_dump(ctx->conf, stdout); + return 0; +} + +static int conf_tool_get(TALLOC_CTX *mem_ctx, + int argc, + const char **argv, + void *private_data) +{ + struct conf_tool_context *ctx = talloc_get_type_abort( + private_data, struct conf_tool_context); + const char *section, *option; + enum conf_type type; + int ret; + bool ok; + const char *s_val = NULL; + int i_val; + bool b_val; + + if (argc != 2) { + cmdline_usage(ctx->cmdline, "get"); + return EINVAL; + } + + section = argv[0]; + option = argv[1]; + + ok = conf_query(ctx->conf, section, option, &type); + if (!ok) { + D_ERR("Configuration option [%s] -> \"%s\" not defined\n", + section, option); + return ENOENT; + } + + ret = conf_load(ctx->conf, ctx->conf_file, true); + if (ret != 0 && ret != ENOENT) { + D_ERR("Failed to load config file %s\n", ctx->conf_file); + return ret; + } + + switch (type) { + case CONF_STRING: + ret = conf_get_string(ctx->conf, + section, + option, + &s_val, + NULL); + break; + + case CONF_INTEGER: + ret = conf_get_integer(ctx->conf, + section, + option, + &i_val, + NULL); + break; + + case CONF_BOOLEAN: + ret = conf_get_boolean(ctx->conf, + section, + option, + &b_val, + NULL); + break; + + default: + D_ERR("Unknown configuration option type\n"); + return EINVAL; + } + + if (ret != 0) { + D_ERR("Failed to get configuration option value\n"); + return ret; + } + + switch (type) { + case CONF_STRING: + printf("%s\n", s_val == NULL ? "" : s_val); + break; + + case CONF_INTEGER: + printf("%d\n", i_val); + break; + + case CONF_BOOLEAN: + printf("%s\n", b_val ? "true" : "false"); + break; + } + + return 0; +} + +static int conf_tool_validate(TALLOC_CTX *mem_ctx, + int argc, + const char **argv, + void *private_data) +{ + struct conf_tool_context *ctx = talloc_get_type_abort( + private_data, struct conf_tool_context); + int ret; + + if (argc != 0) { + cmdline_usage(ctx->cmdline, "validate"); + return EINVAL; + } + + ret = conf_load(ctx->conf, ctx->conf_file, false); + if (ret != 0) { + D_ERR("Failed to load config file %s\n", ctx->conf_file); + return ret; + } + + return 0; +} + +struct cmdline_command conf_commands[] = { + { "dump", conf_tool_dump, + "Dump configuration", NULL }, + { "get", conf_tool_get, + "Get a config value", "<section> <key>" }, + { "validate", conf_tool_validate, + "Validate configuration file", NULL }, + CMDLINE_TABLEEND +}; + +int conf_tool_init(TALLOC_CTX *mem_ctx, + const char *prog, + struct poptOption *options, + int argc, + const char **argv, + bool parse_options, + struct conf_tool_context **result) +{ + struct conf_tool_context *ctx; + int ret; + + ctx = talloc_zero(mem_ctx, struct conf_tool_context); + if (ctx == NULL) { + D_ERR("Memory allocation error\n"); + return ENOMEM; + } + + ret = cmdline_init(ctx, prog, options, conf_commands, &ctx->cmdline); + if (ret != 0) { + D_ERR("Failed to initialize cmdline, ret=%d\n", ret); + talloc_free(ctx); + return ret; + } + + ret = cmdline_parse(ctx->cmdline, argc, argv, parse_options); + if (ret != 0) { + cmdline_usage(ctx->cmdline, NULL); + talloc_free(ctx); + return ret; + } + + *result = ctx; + return 0; +} + +int conf_tool_run(struct conf_tool_context *ctx, int *result) +{ + int ret; + + ctx->conf_file = path_config(ctx); + if (ctx->conf_file == NULL) { + D_ERR("Memory allocation error\n"); + return ENOMEM; + } + + ret = conf_init(ctx, &ctx->conf); + if (ret != 0) { + D_ERR("Failed to initialize config\n"); + return ret; + } + + /* Call functions to initialize config sections/variables */ + + if (! conf_valid(ctx->conf)) { + D_ERR("Failed to define configuration options\n"); + return EINVAL; + } + + ret = cmdline_run(ctx->cmdline, ctx, result); + return ret; +} + +#ifdef CTDB_CONF_TOOL + +static struct { + const char *debug; +} conf_data = { + .debug = "ERROR", +}; + +struct poptOption conf_options[] = { + POPT_AUTOHELP + { "debug", 'd', POPT_ARG_STRING, &conf_data.debug, 0, + "debug level", "ERROR|WARNING|NOTICE|INFO|DEBUG" }, + POPT_TABLEEND +}; + +int main(int argc, const char **argv) +{ + TALLOC_CTX *mem_ctx; + struct conf_tool_context *ctx; + int ret, result; + bool ok; + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + fprintf(stderr, "Memory allocation error\n"); + exit(1); + } + + ret = conf_tool_init(mem_ctx, + "ctdb-config", + conf_options, + argc, + argv, + true, + &ctx); + if (ret != 0) { + talloc_free(mem_ctx); + exit(1); + } + + setup_logging("ctdb-config", DEBUG_STDERR); + ok = debug_level_parse(conf_data.debug, &DEBUGLEVEL); + if (!ok) { + DEBUGLEVEL = DEBUG_ERR; + } + + ret = conf_tool_run(ctx, &result); + if (ret != 0) { + result = 1; + } + + talloc_free(mem_ctx); + exit(result); +} + +#endif /* CTDB_CONF_TOOL */ diff --git a/ctdb/common/conf_tool.h b/ctdb/common/conf_tool.h new file mode 100644 index 00000000000..c77419f7b8d --- /dev/null +++ b/ctdb/common/conf_tool.h @@ -0,0 +1,39 @@ +/* + Config options tool + + Copyright (C) Amitay Isaacs 2018 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __CTDB_CONF_TOOL_H__ +#define __CTDB_CONF_TOOL_H__ + +#include <stdbool.h> +#include <popt.h> +#include <talloc.h> + +struct conf_tool_context; + +int conf_tool_init(TALLOC_CTX *mem_ctx, + const char *prog, + struct poptOption *options, + int argc, + const char **argv, + bool parse_options, + struct conf_tool_context **result); + +int conf_tool_run(struct conf_tool_context *ctx, int *result); + +#endif /* __CTDB_CONF_TOOL_H__ */ diff --git a/ctdb/tests/cunit/config_test_001.sh b/ctdb/tests/cunit/config_test_001.sh new file mode 100755 index 00000000000..6c95c05f0b8 --- /dev/null +++ b/ctdb/tests/cunit/config_test_001.sh @@ -0,0 +1,56 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +PATH="$PATH:$CTDB_SCRIPTS_TOOLS_HELPER_DIR" + +setup_ctdb_base "${TEST_VAR_DIR}" "cunit" + +conffile="${CTDB_BASE}/ctdb.conf" + +remove_files () +{ + rm -f "$conffile" +} + +test_cleanup remove_files + +ok <<EOF +EOF +unit_test ctdb-config dump + +required_result 2 <<EOF +Failed to load config file $conffile +EOF +unit_test ctdb-config validate + +cat > "$conffile" <<EOF +EOF + +ok_null +unit_test ctdb-config validate + +cat > "$conffile" <<EOF +[foobar] +EOF + +required_result 22 <<EOF +conf: unknown section [foobar] +Failed to load config file $conffile +EOF +unit_test ctdb-config validate + +cat > "$conffile" <<EOF +foobar = cat +EOF + +required_result 22 <<EOF +conf: unknown option "foobar" +Failed to load config file $conffile +EOF +unit_test ctdb-config validate + +required_result 2 <<EOF +Configuration option [section] -> "key" not defined +EOF +unit_test ctdb-config get section key diff --git a/ctdb/wscript b/ctdb/wscript index 7c417aab93e..3f0371b78aa 100644 --- a/ctdb/wscript +++ b/ctdb/wscript @@ -460,6 +460,12 @@ def build(bld): deps='''ctdb-util samba-util talloc replace popt''', install_path='${CTDB_HELPER_BINDIR}') + bld.SAMBA_BINARY('ctdb-config', + source='common/conf_tool.c', + cflags='-DCTDB_CONF_TOOL', + deps='''ctdb-util samba-util talloc replace popt''', + install_path='${CTDB_HELPER_BINDIR}') + bld.SAMBA_BINARY('ctdbd', source='server/ctdbd.c ' + bld.SUBDIR('server', |