mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
plugins: add command field to subcommand output.
Makes it possible to write a decent JSON schema, but means we need to carry additional data, so we create a `struct plugin_command`. We remove the unused struct dynamic_plugin, too. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -74,7 +74,7 @@ struct plugins *plugins_new(const tal_t *ctx, struct log_book *log_book,
|
|||||||
p->log = new_log(p, log_book, NULL, "plugin-manager");
|
p->log = new_log(p, log_book, NULL, "plugin-manager");
|
||||||
p->ld = ld;
|
p->ld = ld;
|
||||||
p->startup = true;
|
p->startup = true;
|
||||||
p->json_cmds = tal_arr(p, struct command *, 0);
|
p->plugin_cmds = tal_arr(p, struct plugin_command *, 0);
|
||||||
p->blacklist = tal_arr(p, const char *, 0);
|
p->blacklist = tal_arr(p, const char *, 0);
|
||||||
p->shutdown = false;
|
p->shutdown = false;
|
||||||
p->plugin_idx = 0;
|
p->plugin_idx = 0;
|
||||||
@@ -154,27 +154,27 @@ static void check_plugins_manifests(struct plugins *plugins)
|
|||||||
|
|
||||||
static void check_plugins_initted(struct plugins *plugins)
|
static void check_plugins_initted(struct plugins *plugins)
|
||||||
{
|
{
|
||||||
struct command **json_cmds;
|
struct plugin_command **plugin_cmds;
|
||||||
|
|
||||||
if (!plugins_all_in_state(plugins, INIT_COMPLETE))
|
if (!plugins_all_in_state(plugins, INIT_COMPLETE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Clear commands first, in case callbacks add new ones.
|
/* Clear commands first, in case callbacks add new ones.
|
||||||
* Paranoia, but wouldn't that be a nasty bug to find? */
|
* Paranoia, but wouldn't that be a nasty bug to find? */
|
||||||
json_cmds = plugins->json_cmds;
|
plugin_cmds = plugins->plugin_cmds;
|
||||||
plugins->json_cmds = tal_arr(plugins, struct command *, 0);
|
plugins->plugin_cmds = tal_arr(plugins, struct plugin_command *, 0);
|
||||||
for (size_t i = 0; i < tal_count(json_cmds); i++)
|
for (size_t i = 0; i < tal_count(plugin_cmds); i++)
|
||||||
plugin_cmd_all_complete(plugins, json_cmds[i]);
|
plugin_cmd_all_complete(plugins, plugin_cmds[i]);
|
||||||
tal_free(json_cmds);
|
tal_free(plugin_cmds);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct command_result *plugin_register_all_complete(struct lightningd *ld,
|
struct command_result *plugin_register_all_complete(struct lightningd *ld,
|
||||||
struct command *cmd)
|
struct plugin_command *pcmd)
|
||||||
{
|
{
|
||||||
if (plugins_all_in_state(ld->plugins, INIT_COMPLETE))
|
if (plugins_all_in_state(ld->plugins, INIT_COMPLETE))
|
||||||
return plugin_cmd_all_complete(ld->plugins, cmd);
|
return plugin_cmd_all_complete(ld->plugins, pcmd);
|
||||||
|
|
||||||
tal_arr_expand(&ld->plugins->json_cmds, cmd);
|
tal_arr_expand(&ld->plugins->plugin_cmds, pcmd);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,7 +216,7 @@ static void destroy_plugin(struct plugin *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct plugin *plugin_register(struct plugins *plugins, const char* path TAKES,
|
struct plugin *plugin_register(struct plugins *plugins, const char* path TAKES,
|
||||||
struct command *start_cmd, bool important,
|
struct plugin_command *start_cmd, bool important,
|
||||||
const char *parambuf STEALS,
|
const char *parambuf STEALS,
|
||||||
const jsmntok_t *params STEALS)
|
const jsmntok_t *params STEALS)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -51,8 +51,9 @@ struct plugin {
|
|||||||
struct io_conn *stdin_conn, *stdout_conn;
|
struct io_conn *stdin_conn, *stdout_conn;
|
||||||
struct plugins *plugins;
|
struct plugins *plugins;
|
||||||
const char **plugin_path;
|
const char **plugin_path;
|
||||||
|
|
||||||
/* If there's a json command which ordered this to start */
|
/* If there's a json command which ordered this to start */
|
||||||
struct command *start_cmd;
|
struct plugin_command *start_cmd;
|
||||||
|
|
||||||
enum plugin_state plugin_state;
|
enum plugin_state plugin_state;
|
||||||
|
|
||||||
@@ -122,7 +123,7 @@ struct plugins {
|
|||||||
const char *default_dir;
|
const char *default_dir;
|
||||||
|
|
||||||
/* If there are json commands waiting for plugin resolutions. */
|
/* If there are json commands waiting for plugin resolutions. */
|
||||||
struct command **json_cmds;
|
struct plugin_command **plugin_cmds;
|
||||||
|
|
||||||
/* Blacklist of plugins from --disable-plugin */
|
/* Blacklist of plugins from --disable-plugin */
|
||||||
const char **blacklist;
|
const char **blacklist;
|
||||||
@@ -222,7 +223,7 @@ void plugins_free(struct plugins *plugins);
|
|||||||
*/
|
*/
|
||||||
struct plugin *plugin_register(struct plugins *plugins,
|
struct plugin *plugin_register(struct plugins *plugins,
|
||||||
const char* path TAKES,
|
const char* path TAKES,
|
||||||
struct command *start_cmd,
|
struct plugin_command *start_cmd,
|
||||||
bool important,
|
bool important,
|
||||||
const char *parambuf STEALS,
|
const char *parambuf STEALS,
|
||||||
const jsmntok_t *params STEALS);
|
const jsmntok_t *params STEALS);
|
||||||
@@ -283,7 +284,7 @@ struct plugin *find_plugin_for_command(struct lightningd *ld,
|
|||||||
* plugin_cmd_all_complete().
|
* plugin_cmd_all_complete().
|
||||||
*/
|
*/
|
||||||
struct command_result *plugin_register_all_complete(struct lightningd *ld,
|
struct command_result *plugin_register_all_complete(struct lightningd *ld,
|
||||||
struct command *cmd);
|
struct plugin_command *pcmd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send the configure message to all plugins.
|
* Send the configure message to all plugins.
|
||||||
|
|||||||
@@ -6,21 +6,22 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
/* A dummy structure used to give multiple arguments to callbacks. */
|
/* A dummy structure used to give multiple arguments to callbacks. */
|
||||||
struct dynamic_plugin {
|
struct plugin_command {
|
||||||
struct plugin *plugin;
|
|
||||||
struct command *cmd;
|
struct command *cmd;
|
||||||
|
const char *subcmd;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returned by all subcommands on success.
|
* Returned by all subcommands on success.
|
||||||
*/
|
*/
|
||||||
static struct command_result *plugin_dynamic_list_plugins(struct command *cmd,
|
static struct command_result *plugin_dynamic_list_plugins(struct plugin_command *pcmd,
|
||||||
const struct plugins *plugins)
|
const struct plugins *plugins)
|
||||||
{
|
{
|
||||||
struct json_stream *response;
|
struct json_stream *response;
|
||||||
const struct plugin *p;
|
const struct plugin *p;
|
||||||
|
|
||||||
response = json_stream_success(cmd);
|
response = json_stream_success(pcmd->cmd);
|
||||||
|
json_add_string(response, "command", pcmd->subcmd);
|
||||||
json_array_start(response, "plugins");
|
json_array_start(response, "plugins");
|
||||||
list_for_each(&plugins->plugins, p, list) {
|
list_for_each(&plugins->plugins, p, list) {
|
||||||
json_object_start(response, NULL);
|
json_object_start(response, NULL);
|
||||||
@@ -30,25 +31,25 @@ static struct command_result *plugin_dynamic_list_plugins(struct command *cmd,
|
|||||||
json_object_end(response);
|
json_object_end(response);
|
||||||
}
|
}
|
||||||
json_array_end(response);
|
json_array_end(response);
|
||||||
return command_success(cmd, response);
|
return command_success(pcmd->cmd, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct command_result *plugin_cmd_killed(struct command *cmd,
|
struct command_result *plugin_cmd_killed(struct plugin_command *pcmd,
|
||||||
struct plugin *plugin, const char *msg)
|
struct plugin *plugin, const char *msg)
|
||||||
{
|
{
|
||||||
return command_fail(cmd, PLUGIN_ERROR, "%s: %s", plugin->cmd, msg);
|
return command_fail(pcmd->cmd, PLUGIN_ERROR, "%s: %s", plugin->cmd, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct command_result *plugin_cmd_succeeded(struct command *cmd,
|
struct command_result *plugin_cmd_succeeded(struct plugin_command *pcmd,
|
||||||
struct plugin *plugin)
|
struct plugin *plugin)
|
||||||
{
|
{
|
||||||
return plugin_dynamic_list_plugins(cmd, plugin->plugins);
|
return plugin_dynamic_list_plugins(pcmd, plugin->plugins);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct command_result *plugin_cmd_all_complete(struct plugins *plugins,
|
struct command_result *plugin_cmd_all_complete(struct plugins *plugins,
|
||||||
struct command *cmd)
|
struct plugin_command *pcmd)
|
||||||
{
|
{
|
||||||
return plugin_dynamic_list_plugins(cmd, plugins);
|
return plugin_dynamic_list_plugins(pcmd, plugins);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -56,25 +57,25 @@ struct command_result *plugin_cmd_all_complete(struct plugins *plugins,
|
|||||||
* will give a result 60 seconds later at the most (once init completes).
|
* will give a result 60 seconds later at the most (once init completes).
|
||||||
*/
|
*/
|
||||||
static struct command_result *
|
static struct command_result *
|
||||||
plugin_dynamic_start(struct command *cmd, const char *plugin_path,
|
plugin_dynamic_start(struct plugin_command *pcmd, const char *plugin_path,
|
||||||
const char *buffer, const jsmntok_t *params)
|
const char *buffer, const jsmntok_t *params)
|
||||||
{
|
{
|
||||||
struct plugin *p = plugin_register(cmd->ld->plugins, plugin_path, cmd, false, buffer, params);
|
struct plugin *p = plugin_register(pcmd->cmd->ld->plugins, plugin_path, pcmd, false, buffer, params);
|
||||||
const char *err;
|
const char *err;
|
||||||
|
|
||||||
if (!p)
|
if (!p)
|
||||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
return command_fail(pcmd->cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"%s: already registered",
|
"%s: already registered",
|
||||||
plugin_path);
|
plugin_path);
|
||||||
|
|
||||||
/* This will come back via plugin_cmd_killed or plugin_cmd_succeeded */
|
/* This will come back via plugin_cmd_killed or plugin_cmd_succeeded */
|
||||||
err = plugin_send_getmanifest(p);
|
err = plugin_send_getmanifest(p);
|
||||||
if (err)
|
if (err)
|
||||||
return command_fail(cmd, PLUGIN_ERROR,
|
return command_fail(pcmd->cmd, PLUGIN_ERROR,
|
||||||
"%s: %s",
|
"%s: %s",
|
||||||
plugin_path, err);
|
plugin_path, err);
|
||||||
|
|
||||||
return command_still_pending(cmd);
|
return command_still_pending(pcmd->cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -82,22 +83,22 @@ plugin_dynamic_start(struct command *cmd, const char *plugin_path,
|
|||||||
* all contained plugins recursively and then starts them.
|
* all contained plugins recursively and then starts them.
|
||||||
*/
|
*/
|
||||||
static struct command_result *
|
static struct command_result *
|
||||||
plugin_dynamic_startdir(struct command *cmd, const char *dir_path)
|
plugin_dynamic_startdir(struct plugin_command *pcmd, const char *dir_path)
|
||||||
{
|
{
|
||||||
const char *err;
|
const char *err;
|
||||||
struct command_result *res;
|
struct command_result *res;
|
||||||
|
|
||||||
err = add_plugin_dir(cmd->ld->plugins, dir_path, false);
|
err = add_plugin_dir(pcmd->cmd->ld->plugins, dir_path, false);
|
||||||
if (err)
|
if (err)
|
||||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS, "%s", err);
|
return command_fail(pcmd->cmd, JSONRPC2_INVALID_PARAMS, "%s", err);
|
||||||
|
|
||||||
/* If none added, this calls plugin_cmd_all_complete immediately */
|
/* If none added, this calls plugin_cmd_all_complete immediately */
|
||||||
res = plugin_register_all_complete(cmd->ld, cmd);
|
res = plugin_register_all_complete(pcmd->cmd->ld, pcmd);
|
||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
plugins_send_getmanifest(cmd->ld->plugins);
|
plugins_send_getmanifest(pcmd->cmd->ld->plugins);
|
||||||
return command_still_pending(cmd);
|
return command_still_pending(pcmd->cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct command_result *
|
static struct command_result *
|
||||||
@@ -116,6 +117,7 @@ plugin_dynamic_stop(struct command *cmd, const char *plugin_name)
|
|||||||
plugin_kill(p, LOG_INFORM,
|
plugin_kill(p, LOG_INFORM,
|
||||||
"stopped by lightningd via RPC");
|
"stopped by lightningd via RPC");
|
||||||
response = json_stream_success(cmd);
|
response = json_stream_success(cmd);
|
||||||
|
json_add_string(response, "command", "stop");
|
||||||
json_add_string(response, "result",
|
json_add_string(response, "result",
|
||||||
take(tal_fmt(NULL, "Successfully stopped %s.",
|
take(tal_fmt(NULL, "Successfully stopped %s.",
|
||||||
plugin_name)));
|
plugin_name)));
|
||||||
@@ -131,20 +133,20 @@ plugin_dynamic_stop(struct command *cmd, const char *plugin_name)
|
|||||||
* Look for additions in the default plugin directory.
|
* Look for additions in the default plugin directory.
|
||||||
*/
|
*/
|
||||||
static struct command_result *
|
static struct command_result *
|
||||||
plugin_dynamic_rescan_plugins(struct command *cmd)
|
plugin_dynamic_rescan_plugins(struct plugin_command *pcmd)
|
||||||
{
|
{
|
||||||
struct command_result *res;
|
struct command_result *res;
|
||||||
|
|
||||||
/* This will not fail on "already registered" error. */
|
/* This will not fail on "already registered" error. */
|
||||||
plugins_add_default_dir(cmd->ld->plugins);
|
plugins_add_default_dir(pcmd->cmd->ld->plugins);
|
||||||
|
|
||||||
/* If none added, this calls plugin_cmd_all_complete immediately */
|
/* If none added, this calls plugin_cmd_all_complete immediately */
|
||||||
res = plugin_register_all_complete(cmd->ld, cmd);
|
res = plugin_register_all_complete(pcmd->cmd->ld, pcmd);
|
||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
plugins_send_getmanifest(cmd->ld->plugins);
|
plugins_send_getmanifest(pcmd->cmd->ld->plugins);
|
||||||
return command_still_pending(cmd);
|
return command_still_pending(pcmd->cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -156,6 +158,7 @@ static struct command_result *json_plugin_control(struct command *cmd,
|
|||||||
const jsmntok_t *obj UNNEEDED,
|
const jsmntok_t *obj UNNEEDED,
|
||||||
const jsmntok_t *params)
|
const jsmntok_t *params)
|
||||||
{
|
{
|
||||||
|
struct plugin_command *pcmd;
|
||||||
const char *subcmd;
|
const char *subcmd;
|
||||||
subcmd = param_subcommand(cmd, buffer, params,
|
subcmd = param_subcommand(cmd, buffer, params,
|
||||||
"start", "stop", "startdir",
|
"start", "stop", "startdir",
|
||||||
@@ -163,6 +166,10 @@ static struct command_result *json_plugin_control(struct command *cmd,
|
|||||||
if (!subcmd)
|
if (!subcmd)
|
||||||
return command_param_failed();
|
return command_param_failed();
|
||||||
|
|
||||||
|
pcmd = tal(cmd, struct plugin_command);
|
||||||
|
pcmd->cmd = cmd;
|
||||||
|
pcmd->subcmd = subcmd;
|
||||||
|
|
||||||
if (streq(subcmd, "stop")) {
|
if (streq(subcmd, "stop")) {
|
||||||
const char *plugin_name;
|
const char *plugin_name;
|
||||||
|
|
||||||
@@ -202,7 +209,7 @@ static struct command_result *json_plugin_control(struct command *cmd,
|
|||||||
"plugin") - 1, 1);
|
"plugin") - 1, 1);
|
||||||
}
|
}
|
||||||
if (access(plugin_path, X_OK) == 0)
|
if (access(plugin_path, X_OK) == 0)
|
||||||
return plugin_dynamic_start(cmd, plugin_path,
|
return plugin_dynamic_start(pcmd, plugin_path,
|
||||||
buffer, mod_params);
|
buffer, mod_params);
|
||||||
else
|
else
|
||||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
@@ -218,7 +225,7 @@ static struct command_result *json_plugin_control(struct command *cmd,
|
|||||||
return command_param_failed();
|
return command_param_failed();
|
||||||
|
|
||||||
if (access(dir_path, F_OK) == 0)
|
if (access(dir_path, F_OK) == 0)
|
||||||
return plugin_dynamic_startdir(cmd, dir_path);
|
return plugin_dynamic_startdir(pcmd, dir_path);
|
||||||
else
|
else
|
||||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||||
"Could not open %s", dir_path);
|
"Could not open %s", dir_path);
|
||||||
@@ -228,14 +235,14 @@ static struct command_result *json_plugin_control(struct command *cmd,
|
|||||||
NULL))
|
NULL))
|
||||||
return command_param_failed();
|
return command_param_failed();
|
||||||
|
|
||||||
return plugin_dynamic_rescan_plugins(cmd);
|
return plugin_dynamic_rescan_plugins(pcmd);
|
||||||
} else if (streq(subcmd, "list")) {
|
} else if (streq(subcmd, "list")) {
|
||||||
if (!param(cmd, buffer, params,
|
if (!param(cmd, buffer, params,
|
||||||
p_req("subcommand", param_ignore, cmd),
|
p_req("subcommand", param_ignore, cmd),
|
||||||
NULL))
|
NULL))
|
||||||
return command_param_failed();
|
return command_param_failed();
|
||||||
|
|
||||||
return plugin_dynamic_list_plugins(cmd, cmd->ld->plugins);
|
return plugin_dynamic_list_plugins(pcmd, cmd->ld->plugins);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* subcmd must be one of the above: param_subcommand checked it! */
|
/* subcmd must be one of the above: param_subcommand checked it! */
|
||||||
|
|||||||
@@ -3,16 +3,18 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <lightningd/plugin.h>
|
#include <lightningd/plugin.h>
|
||||||
|
|
||||||
|
struct plugin_command;
|
||||||
|
|
||||||
/* Plugin startup failed */
|
/* Plugin startup failed */
|
||||||
struct command_result *plugin_cmd_killed(struct command *cmd,
|
struct command_result *plugin_cmd_killed(struct plugin_command *pcmd,
|
||||||
struct plugin *plugin, const char *msg);
|
struct plugin *plugin, const char *msg);
|
||||||
|
|
||||||
/* Plugin startup succeeded */
|
/* Plugin startup succeeded */
|
||||||
struct command_result *plugin_cmd_succeeded(struct command *cmd,
|
struct command_result *plugin_cmd_succeeded(struct plugin_command *pcmd,
|
||||||
struct plugin *plugin);
|
struct plugin *plugin);
|
||||||
|
|
||||||
/* All plugins succeeded/failed */
|
/* All plugins succeeded/failed */
|
||||||
struct command_result *plugin_cmd_all_complete(struct plugins *plugins,
|
struct command_result *plugin_cmd_all_complete(struct plugins *plugins,
|
||||||
struct command *cmd);
|
struct plugin_command *pcmd);
|
||||||
|
|
||||||
#endif /* LIGHTNING_LIGHTNINGD_PLUGIN_CONTROL_H */
|
#endif /* LIGHTNING_LIGHTNINGD_PLUGIN_CONTROL_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user