mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-24 01:24:26 +01:00
Plugin: support extra args to "start".
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Changelog-Added: Plugins: `start` command can now take plugin-specific parameters.
This commit is contained in:
@@ -348,7 +348,7 @@ static char *opt_add_plugin(const char *arg, struct lightningd *ld)
|
||||
log_info(ld->log, "%s: disabled via disable-plugin", arg);
|
||||
return NULL;
|
||||
}
|
||||
plugin_register(ld->plugins, arg, NULL, false);
|
||||
plugin_register(ld->plugins, arg, NULL, false, NULL, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -375,7 +375,7 @@ static char *opt_important_plugin(const char *arg, struct lightningd *ld)
|
||||
log_info(ld->log, "%s: disabled via disable-plugin", arg);
|
||||
return NULL;
|
||||
}
|
||||
plugin_register(ld->plugins, arg, NULL, true);
|
||||
plugin_register(ld->plugins, arg, NULL, true, NULL, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <ccan/array_size/array_size.h>
|
||||
#include <ccan/list/list.h>
|
||||
#include <ccan/mem/mem.h>
|
||||
#include <ccan/opt/opt.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <ccan/utf8/utf8.h>
|
||||
@@ -174,7 +175,9 @@ static void destroy_plugin(struct plugin *p)
|
||||
}
|
||||
|
||||
struct plugin *plugin_register(struct plugins *plugins, const char* path TAKES,
|
||||
struct command *start_cmd, bool important)
|
||||
struct command *start_cmd, bool important,
|
||||
const char *parambuf STEALS,
|
||||
const jsmntok_t *params STEALS)
|
||||
{
|
||||
struct plugin *p, *p_temp;
|
||||
|
||||
@@ -212,6 +215,8 @@ struct plugin *plugin_register(struct plugins *plugins, const char* path TAKES,
|
||||
list_head_init(&p->pending_rpccalls);
|
||||
|
||||
p->important = important;
|
||||
p->parambuf = tal_steal(p, parambuf);
|
||||
p->params = tal_steal(p, params);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -1154,6 +1159,48 @@ static const char *plugin_hooks_add(struct plugin *plugin, const char *buffer,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct plugin_opt *plugin_opt_find(struct plugin *plugin,
|
||||
const char *name, size_t namelen)
|
||||
{
|
||||
struct plugin_opt *opt;
|
||||
|
||||
list_for_each(&plugin->plugin_opts, opt, list) {
|
||||
/* Trim the `--` that we added before */
|
||||
if (memeqstr(name, namelen, opt->name + 2))
|
||||
return opt;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* start command might have included plugin-specific parameters */
|
||||
static const char *plugin_add_params(struct plugin *plugin)
|
||||
{
|
||||
size_t i;
|
||||
const jsmntok_t *t;
|
||||
|
||||
if (!plugin->params)
|
||||
return NULL;
|
||||
|
||||
json_for_each_obj(i, t, plugin->params) {
|
||||
struct plugin_opt *popt;
|
||||
char *err;
|
||||
|
||||
popt = plugin_opt_find(plugin,
|
||||
plugin->parambuf + t->start,
|
||||
t->end - t->start);
|
||||
if (!popt) {
|
||||
return tal_fmt(plugin, "unknown parameter %.*s",
|
||||
json_tok_full_len(t),
|
||||
json_tok_full(plugin->parambuf, t));
|
||||
}
|
||||
err = plugin_opt_set(json_strdup(tmpctx, plugin->parambuf,
|
||||
t + 1), popt);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void plugin_manifest_timeout(struct plugin *plugin)
|
||||
{
|
||||
bool startup = plugin->plugins->startup;
|
||||
@@ -1243,6 +1290,8 @@ static const char *plugin_parse_getmanifest_response(const char *buffer,
|
||||
err = plugin_subscriptions_add(plugin, buffer, resulttok);
|
||||
if (!err)
|
||||
err = plugin_hooks_add(plugin, buffer, resulttok);
|
||||
if (!err)
|
||||
err = plugin_add_params(plugin);
|
||||
|
||||
plugin->plugin_state = NEEDS_INIT;
|
||||
return err;
|
||||
@@ -1360,7 +1409,8 @@ char *add_plugin_dir(struct plugins *plugins, const char *dir, bool error_ok)
|
||||
log_info(plugins->log, "%s: disabled via disable-plugin",
|
||||
fullpath);
|
||||
} else {
|
||||
p = plugin_register(plugins, fullpath, NULL, false);
|
||||
p = plugin_register(plugins, fullpath, NULL, false,
|
||||
NULL, NULL);
|
||||
if (!p && !error_ok)
|
||||
return tal_fmt(NULL, "Failed to register %s: %s",
|
||||
fullpath, strerror(errno));
|
||||
@@ -1807,7 +1857,8 @@ void plugins_set_builtin_plugins_dir(struct plugins *plugins,
|
||||
take(path_join(NULL, dir,
|
||||
list_of_builtin_plugins[i])),
|
||||
NULL,
|
||||
/* important = */ true);
|
||||
/* important = */ true,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
struct plugin_destroyed {
|
||||
|
||||
@@ -88,6 +88,10 @@ struct plugin {
|
||||
/* If set, the plugin is so important that if it terminates early,
|
||||
* C-lightning should terminate as well. */
|
||||
bool important;
|
||||
|
||||
/* Parameters for dynamically-started plugins. */
|
||||
const char *parambuf;
|
||||
const jsmntok_t *params;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -200,6 +204,8 @@ void plugins_free(struct plugins *plugins);
|
||||
* @param path: The path of the executable for this plugin
|
||||
* @param start_cmd: The optional JSON command which caused this.
|
||||
* @param important: The plugin is important.
|
||||
* @param parambuf: NULL, or the JSON buffer for extra parameters.
|
||||
* @param params: NULL, or the tokens for extra parameters.
|
||||
*
|
||||
* If @start_cmd, then plugin_cmd_killed or plugin_cmd_succeeded will be called
|
||||
* on it eventually.
|
||||
@@ -207,7 +213,10 @@ void plugins_free(struct plugins *plugins);
|
||||
struct plugin *plugin_register(struct plugins *plugins,
|
||||
const char* path TAKES,
|
||||
struct command *start_cmd,
|
||||
bool important);
|
||||
bool important,
|
||||
const char *parambuf STEALS,
|
||||
const jsmntok_t *params STEALS);
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the provided name matches a plugin command
|
||||
|
||||
@@ -56,9 +56,10 @@ struct command_result *plugin_cmd_all_complete(struct plugins *plugins,
|
||||
* will give a result 60 seconds later at the most (once init completes).
|
||||
*/
|
||||
static struct command_result *
|
||||
plugin_dynamic_start(struct command *cmd, const char *plugin_path)
|
||||
plugin_dynamic_start(struct command *cmd, const char *plugin_path,
|
||||
const char *buffer, const jsmntok_t *params)
|
||||
{
|
||||
struct plugin *p = plugin_register(cmd->ld->plugins, plugin_path, cmd, false);
|
||||
struct plugin *p = plugin_register(cmd->ld->plugins, plugin_path, cmd, false, buffer, params);
|
||||
const char *err;
|
||||
|
||||
if (!p)
|
||||
@@ -173,15 +174,35 @@ static struct command_result *json_plugin_control(struct command *cmd,
|
||||
return plugin_dynamic_stop(cmd, plugin_name);
|
||||
} else if (streq(subcmd, "start")) {
|
||||
const char *plugin_path;
|
||||
jsmntok_t *mod_params;
|
||||
|
||||
if (!param(cmd, buffer, params,
|
||||
p_req("subcommand", param_ignore, cmd),
|
||||
p_req("plugin", param_string, &plugin_path),
|
||||
p_opt_any(),
|
||||
NULL))
|
||||
return command_param_failed();
|
||||
|
||||
/* Manually parse any remaining options (only for objects,
|
||||
* since plugin options must be explicitly named!). */
|
||||
if (params->type == JSMN_ARRAY) {
|
||||
if (params->size != 2)
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"Extra parameters must be in object");
|
||||
mod_params = NULL;
|
||||
} else {
|
||||
mod_params = json_tok_copy(cmd, params);
|
||||
|
||||
json_tok_remove(&mod_params, mod_params,
|
||||
json_get_member(buffer, mod_params,
|
||||
"subcommand") - 1, 1);
|
||||
json_tok_remove(&mod_params, mod_params,
|
||||
json_get_member(buffer, mod_params,
|
||||
"plugin") - 1, 1);
|
||||
}
|
||||
if (access(plugin_path, X_OK) == 0)
|
||||
return plugin_dynamic_start(cmd, plugin_path);
|
||||
return plugin_dynamic_start(cmd, plugin_path,
|
||||
buffer, mod_params);
|
||||
else
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"%s is not executable: %s",
|
||||
|
||||
Reference in New Issue
Block a user