mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-15 11:59:16 +01:00
plugins: libplugin support for dynamic config options.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
aa5c7e763f
commit
a65f2ef22a
2 changed files with 68 additions and 18 deletions
|
@ -915,6 +915,7 @@ handle_getmanifest(struct command *getmanifest_cmd,
|
|||
json_add_string(params, "type", p->opts[i].type);
|
||||
json_add_string(params, "description", p->opts[i].description);
|
||||
json_add_bool(params, "deprecated", p->opts[i].deprecated);
|
||||
json_add_bool(params, "dynamic", p->opts[i].dynamic);
|
||||
json_object_end(params);
|
||||
}
|
||||
json_array_end(params);
|
||||
|
@ -1136,6 +1137,15 @@ static struct feature_set *json_to_feature_set(struct plugin *plugin,
|
|||
return fset;
|
||||
}
|
||||
|
||||
static struct plugin_option *find_opt(struct plugin *plugin, const char *name)
|
||||
{
|
||||
for (size_t i = 0; i < tal_count(plugin->opts); i++) {
|
||||
if (streq(plugin->opts[i].name, name))
|
||||
return &plugin->opts[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct command_result *handle_init(struct command *cmd,
|
||||
const char *buf,
|
||||
const jsmntok_t *params)
|
||||
|
@ -1197,19 +1207,17 @@ static struct command_result *handle_init(struct command *cmd,
|
|||
|
||||
opttok = json_get_member(buf, params, "options");
|
||||
json_for_each_obj(i, t, opttok) {
|
||||
char *opt = json_strdup(NULL, buf, t);
|
||||
for (size_t optnum = 0; optnum < tal_count(p->opts); optnum++) {
|
||||
char *problem;
|
||||
if (!streq(p->opts[optnum].name, opt))
|
||||
continue;
|
||||
problem = p->opts[optnum].handle(p, json_strdup(opt, buf, t+1),
|
||||
p->opts[optnum].arg);
|
||||
if (problem)
|
||||
plugin_err(p, "option '%s': %s",
|
||||
p->opts[optnum].name, problem);
|
||||
break;
|
||||
}
|
||||
tal_free(opt);
|
||||
const char *name, *problem;
|
||||
struct plugin_option *popt;
|
||||
|
||||
name = json_strdup(tmpctx, buf, t);
|
||||
popt = find_opt(p, name);
|
||||
if (!popt)
|
||||
plugin_err(p, "lightningd specified unknown option '%s'?", name);
|
||||
|
||||
problem = popt->handle(p, json_strdup(tmpctx, buf, t+1), popt->arg);
|
||||
if (problem)
|
||||
plugin_err(p, "option '%s': %s", popt->name, problem);
|
||||
}
|
||||
|
||||
if (p->init) {
|
||||
|
@ -1638,6 +1646,41 @@ static void ld_command_handle(struct plugin *plugin,
|
|||
}
|
||||
}
|
||||
|
||||
/* Dynamic parameters */
|
||||
if (streq(cmd->methodname, "setconfig")) {
|
||||
const jsmntok_t *valtok;
|
||||
const char *config, *val, *problem;
|
||||
struct plugin_option *popt;
|
||||
struct command_result *ret;
|
||||
config = json_strdup(tmpctx, plugin->buffer,
|
||||
json_get_member(plugin->buffer, paramstok, "config"));
|
||||
popt = find_opt(plugin, config);
|
||||
if (!popt) {
|
||||
plugin_err(plugin,
|
||||
"lightningd setconfig unknown option '%s'?",
|
||||
config);
|
||||
}
|
||||
if (!popt->dynamic) {
|
||||
plugin_err(plugin,
|
||||
"lightningd setconfig non-dynamic option '%s'?",
|
||||
config);
|
||||
}
|
||||
valtok = json_get_member(plugin->buffer, paramstok, "val");
|
||||
if (valtok)
|
||||
val = json_strdup(tmpctx, plugin->buffer, valtok);
|
||||
else
|
||||
val = "true";
|
||||
|
||||
problem = popt->handle(plugin, val, popt->arg);
|
||||
if (problem)
|
||||
ret = command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"%s", problem);
|
||||
else
|
||||
ret = command_finished(cmd, jsonrpc_stream_success(cmd));
|
||||
assert(ret == &complete);
|
||||
return;
|
||||
}
|
||||
|
||||
plugin_err(plugin, "Unknown command '%s'", cmd->methodname);
|
||||
}
|
||||
|
||||
|
@ -1842,6 +1885,7 @@ static struct plugin *new_plugin(const tal_t *ctx,
|
|||
o.handle = va_arg(ap, char *(*)(struct plugin *, const char *str, void *arg));
|
||||
o.arg = va_arg(ap, void *);
|
||||
o.deprecated = va_arg(ap, int); /* bool gets promoted! */
|
||||
o.dynamic = va_arg(ap, int); /* bool gets promoted! */
|
||||
tal_arr_expand(&p->opts, o);
|
||||
}
|
||||
|
||||
|
|
|
@ -81,6 +81,8 @@ struct plugin_option {
|
|||
void *arg;
|
||||
/* If true, this options *disabled* if allow-deprecated-apis = false */
|
||||
bool deprecated;
|
||||
/* If true, allow setting after plugin has initialized */
|
||||
bool dynamic;
|
||||
};
|
||||
|
||||
/* Create an array of these, one for each notification you subscribe to. */
|
||||
|
@ -401,7 +403,7 @@ static inline void *plugin_option_cb_check(char *(*set)(struct plugin *plugin,
|
|||
}
|
||||
|
||||
/* Macro to define arguments */
|
||||
#define plugin_option_(name, type, description, set, arg, deprecated) \
|
||||
#define plugin_option_(name, type, description, set, arg, deprecated, dynamic) \
|
||||
(name), \
|
||||
(type), \
|
||||
(description), \
|
||||
|
@ -410,13 +412,17 @@ static inline void *plugin_option_cb_check(char *(*set)(struct plugin *plugin,
|
|||
struct plugin *, \
|
||||
const char *)), \
|
||||
(arg), \
|
||||
(deprecated)
|
||||
(deprecated), \
|
||||
(dynamic)
|
||||
|
||||
#define plugin_option(name, type, description, set, arg) \
|
||||
plugin_option_((name), (type), (description), (set), (arg), false)
|
||||
plugin_option_((name), (type), (description), (set), (arg), false, false)
|
||||
|
||||
#define plugin_option_deprecated(name, type, description, set, arg) \
|
||||
plugin_option_((name), (type), (description), (set), (arg), true)
|
||||
#define plugin_option_dynamic(name, type, description, set, arg) \
|
||||
plugin_option_((name), (type), (description), (set), (arg), false, true)
|
||||
|
||||
#define plugin_option_deprecated(name, type, description, set, arg) \
|
||||
plugin_option_((name), (type), (description), (set), (arg), true, false)
|
||||
|
||||
/* Standard helpers */
|
||||
char *u64_option(struct plugin *plugin, const char *arg, u64 *i);
|
||||
|
|
Loading…
Add table
Reference in a new issue