1453 lines
61 KiB
Diff
1453 lines
61 KiB
Diff
From ea636bc7b290325a8d11f56c4ca461d4d010643d Mon Sep 17 00:00:00 2001
|
|
From: Ken Gaillot <kgaillot@redhat.com>
|
|
Date: Mon, 14 Sep 2020 16:29:19 -0500
|
|
Subject: [PATCH 1/6] Refactor: tools: restructure crm_resource command-line
|
|
resource configuration
|
|
|
|
... to allow (future) options other than --validate to use the command-line
|
|
resource configuration options.
|
|
|
|
I had planned to use this for a project but went in different direction, so
|
|
nothing more is expected to use it for now, but I think it's still worthwhile
|
|
to help isolate different parts of code.
|
|
---
|
|
tools/crm_resource.c | 189 ++++++++++++++++++++++++++-------------------------
|
|
1 file changed, 98 insertions(+), 91 deletions(-)
|
|
|
|
diff --git a/tools/crm_resource.c b/tools/crm_resource.c
|
|
index 2fc9a86..1dcb0f0 100644
|
|
--- a/tools/crm_resource.c
|
|
+++ b/tools/crm_resource.c
|
|
@@ -1,5 +1,5 @@
|
|
/*
|
|
- * Copyright 2004-2020 the Pacemaker project contributors
|
|
+ * Copyright 2004-2021 the Pacemaker project contributors
|
|
*
|
|
* The version control history for this file may have further details.
|
|
*
|
|
@@ -66,39 +66,46 @@ enum rsc_command {
|
|
};
|
|
|
|
struct {
|
|
- enum rsc_command rsc_cmd; // The crm_resource command to perform
|
|
- const char *attr_set_type;
|
|
- int cib_options;
|
|
- gboolean clear_expired;
|
|
- int find_flags; /* Flags to use when searching for resource */
|
|
- gboolean force;
|
|
- gchar *host_uname;
|
|
- gchar *interval_spec;
|
|
- gchar *move_lifetime;
|
|
- gchar *operation;
|
|
- GHashTable *override_params;
|
|
- gchar *prop_id;
|
|
- char *prop_name;
|
|
- gchar *prop_set;
|
|
- gchar *prop_value;
|
|
- gboolean recursive;
|
|
- gchar **remainder;
|
|
- gboolean require_cib; // Whether command requires CIB connection
|
|
- gboolean require_crmd; /* whether command requires controller connection */
|
|
- gboolean require_dataset; /* whether command requires populated dataset instance */
|
|
- gboolean require_resource; /* whether command requires that resource be specified */
|
|
- int resource_verbose;
|
|
- gchar *rsc_id;
|
|
- gchar *rsc_type;
|
|
- gboolean promoted_role_only;
|
|
- int timeout_ms;
|
|
- char *agent_spec; // Standard and/or provider and/or agent
|
|
- char *v_agent;
|
|
- char *v_class;
|
|
- char *v_provider;
|
|
- gboolean validate_cmdline; /* whether we are just validating based on command line options */
|
|
- GHashTable *validate_options;
|
|
- gchar *xml_file;
|
|
+ enum rsc_command rsc_cmd; // crm_resource command to perform
|
|
+
|
|
+ // Infrastructure that given command needs to work
|
|
+ gboolean require_cib; // Whether command requires CIB IPC
|
|
+ int cib_options; // Options to use with CIB IPC calls
|
|
+ gboolean require_crmd; // Whether command requires controller IPC
|
|
+ gboolean require_dataset; // Whether command requires populated data set
|
|
+ gboolean require_resource; // Whether command requires resource specified
|
|
+ int find_flags; // Flags to use when searching for resource
|
|
+
|
|
+ // Command-line option values
|
|
+ gchar *rsc_id; // Value of --resource
|
|
+ gchar *rsc_type; // Value of --resource-type
|
|
+ gboolean force; // --force was given
|
|
+ gboolean clear_expired; // --expired was given
|
|
+ gboolean recursive; // --recursive was given
|
|
+ gboolean promoted_role_only; // --master was given
|
|
+ gchar *host_uname; // Value of --node
|
|
+ gchar *interval_spec; // Value of --interval
|
|
+ gchar *move_lifetime; // Value of --lifetime
|
|
+ gchar *operation; // Value of --operation
|
|
+ const char *attr_set_type; // Instance, meta, or utilization attribute
|
|
+ gchar *prop_id; // --nvpair (attribute XML ID)
|
|
+ char *prop_name; // Attribute name
|
|
+ gchar *prop_set; // --set-name (attribute block XML ID)
|
|
+ gchar *prop_value; // --parameter-value (attribute value)
|
|
+ int timeout_ms; // Parsed from --timeout value
|
|
+ char *agent_spec; // Standard and/or provider and/or agent
|
|
+ gchar *xml_file; // Value of (deprecated) --xml-file
|
|
+
|
|
+ // Resource configuration specified via command-line arguments
|
|
+ gboolean cmdline_config; // Resource configuration was via arguments
|
|
+ char *v_agent; // Value of --agent
|
|
+ char *v_class; // Value of --class
|
|
+ char *v_provider; // Value of --provider
|
|
+ GHashTable *cmdline_params; // Resource parameters specified
|
|
+
|
|
+ // Positional command-line arguments
|
|
+ gchar **remainder; // Positional arguments as given
|
|
+ GHashTable *override_params; // Resource parameter values that override config
|
|
} options = {
|
|
.attr_set_type = XML_TAG_ATTR_SETS,
|
|
.cib_options = cib_sync_call,
|
|
@@ -533,28 +540,6 @@ static GOptionEntry advanced_entries[] = {
|
|
{ NULL }
|
|
};
|
|
|
|
-static GOptionEntry validate_entries[] = {
|
|
- { "class", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, class_cb,
|
|
- "The standard the resource agent confirms to (for example, ocf).\n"
|
|
- INDENT "Use with --agent, --provider, --option, and --validate.",
|
|
- "CLASS" },
|
|
- { "agent", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, agent_provider_cb,
|
|
- "The agent to use (for example, IPaddr). Use with --class,\n"
|
|
- INDENT "--provider, --option, and --validate.",
|
|
- "AGENT" },
|
|
- { "provider", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, agent_provider_cb,
|
|
- "The vendor that supplies the resource agent (for example,\n"
|
|
- INDENT "heartbeat). Use with --class, --agent, --option, and --validate.",
|
|
- "PROVIDER" },
|
|
- { "option", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, option_cb,
|
|
- "Specify a device configuration parameter as NAME=VALUE (may be\n"
|
|
- INDENT "specified multiple times). Use with --validate and without the\n"
|
|
- INDENT "-r option.",
|
|
- "PARAM" },
|
|
-
|
|
- { NULL }
|
|
-};
|
|
-
|
|
static GOptionEntry addl_entries[] = {
|
|
{ "node", 'N', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, &options.host_uname,
|
|
"Node name",
|
|
@@ -582,6 +567,23 @@ static GOptionEntry addl_entries[] = {
|
|
{ "interval", 'I', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, &options.interval_spec,
|
|
"Interval of operation to clear (default 0) (with -C -r -n)",
|
|
"N" },
|
|
+ { "class", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, class_cb,
|
|
+ "The standard the resource agent conforms to (for example, ocf).\n"
|
|
+ INDENT "Use with --agent, --provider, --option, and --validate.",
|
|
+ "CLASS" },
|
|
+ { "agent", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, agent_provider_cb,
|
|
+ "The agent to use (for example, IPaddr). Use with --class,\n"
|
|
+ INDENT "--provider, --option, and --validate.",
|
|
+ "AGENT" },
|
|
+ { "provider", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, agent_provider_cb,
|
|
+ "The vendor that supplies the resource agent (for example,\n"
|
|
+ INDENT "heartbeat). Use with --class, --agent, --option, and --validate.",
|
|
+ "PROVIDER" },
|
|
+ { "option", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, option_cb,
|
|
+ "Specify a device configuration parameter as NAME=VALUE (may be\n"
|
|
+ INDENT "specified multiple times). Use with --validate and without the\n"
|
|
+ INDENT "-r option.",
|
|
+ "PARAM" },
|
|
{ "set-name", 's', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, &options.prop_set,
|
|
"(Advanced) XML ID of attributes element to use (with -p, -d)",
|
|
"ID" },
|
|
@@ -608,7 +610,7 @@ static GOptionEntry addl_entries[] = {
|
|
|
|
gboolean
|
|
agent_provider_cb(const gchar *option_name, const gchar *optarg, gpointer data, GError **error) {
|
|
- options.validate_cmdline = TRUE;
|
|
+ options.cmdline_config = TRUE;
|
|
options.require_resource = FALSE;
|
|
|
|
if (pcmk__str_eq(option_name, "--provider", pcmk__str_casei)) {
|
|
@@ -654,7 +656,7 @@ class_cb(const gchar *option_name, const gchar *optarg, gpointer data, GError **
|
|
options.v_class = strdup(optarg);
|
|
}
|
|
|
|
- options.validate_cmdline = TRUE;
|
|
+ options.cmdline_config = TRUE;
|
|
options.require_resource = FALSE;
|
|
return TRUE;
|
|
}
|
|
@@ -762,10 +764,10 @@ option_cb(const gchar *option_name, const gchar *optarg, gpointer data,
|
|
if (pcmk_scan_nvpair(optarg, &name, &value) != 2) {
|
|
return FALSE;
|
|
}
|
|
- if (options.validate_options == NULL) {
|
|
- options.validate_options = crm_str_table_new();
|
|
+ if (options.cmdline_params == NULL) {
|
|
+ options.cmdline_params = crm_str_table_new();
|
|
}
|
|
- g_hash_table_replace(options.validate_options, name, value);
|
|
+ g_hash_table_replace(options.cmdline_params, name, value);
|
|
return TRUE;
|
|
}
|
|
|
|
@@ -1365,17 +1367,18 @@ show_metadata(pcmk__output_t *out, const char *agent_spec, crm_exit_t *exit_code
|
|
}
|
|
|
|
static void
|
|
-validate_cmdline(crm_exit_t *exit_code)
|
|
+validate_cmdline_config(void)
|
|
{
|
|
- // -r cannot be used with any of --class, --agent, or --provider
|
|
+ // Cannot use both --resource and command-line resource configuration
|
|
if (options.rsc_id != NULL) {
|
|
g_set_error(&error, PCMK__EXITC_ERROR, CRM_EX_USAGE,
|
|
"--resource cannot be used with --class, --agent, and --provider");
|
|
|
|
- // If --class, --agent, or --provider are given, --validate must also be given.
|
|
+ // Not all commands support command-line resource configuration
|
|
} else if (options.rsc_cmd != cmd_execute_agent) {
|
|
g_set_error(&error, PCMK__EXITC_ERROR, CRM_EX_USAGE,
|
|
- "--class, --agent, and --provider require --validate");
|
|
+ "--class, --agent, and --provider can only be used with "
|
|
+ "--validate");
|
|
|
|
// Not all of --class, --agent, and --provider need to be given. Not all
|
|
// classes support the concept of a provider. Check that what we were given
|
|
@@ -1398,15 +1401,16 @@ validate_cmdline(crm_exit_t *exit_code)
|
|
options.v_agent ? options.v_agent : "");
|
|
}
|
|
|
|
- if (error == NULL) {
|
|
- if (options.validate_options == NULL) {
|
|
- options.validate_options = crm_str_table_new();
|
|
- }
|
|
- *exit_code = cli_resource_execute_from_params(out, "test", options.v_class, options.v_provider, options.v_agent,
|
|
- "validate-all", options.validate_options,
|
|
- options.override_params, options.timeout_ms,
|
|
- options.resource_verbose, options.force);
|
|
+ if (error != NULL) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (options.cmdline_params == NULL) {
|
|
+ options.cmdline_params = crm_str_table_new();
|
|
}
|
|
+ options.require_resource = FALSE;
|
|
+ options.require_dataset = FALSE;
|
|
+ options.require_cib = FALSE;
|
|
}
|
|
|
|
static GOptionContext *
|
|
@@ -1467,8 +1471,6 @@ build_arg_context(pcmk__common_args_t *args, GOptionGroup **group) {
|
|
"Show command help", command_entries);
|
|
pcmk__add_arg_group(context, "locations", "Locations:",
|
|
"Show location help", location_entries);
|
|
- pcmk__add_arg_group(context, "validate", "Validate:",
|
|
- "Show validate help", validate_entries);
|
|
pcmk__add_arg_group(context, "advanced", "Advanced:",
|
|
"Show advanced option help", advanced_entries);
|
|
pcmk__add_arg_group(context, "additional", "Additional Options:",
|
|
@@ -1512,7 +1514,6 @@ main(int argc, char **argv)
|
|
goto done;
|
|
}
|
|
|
|
- options.resource_verbose = args->verbosity;
|
|
out->quiet = args->quiet;
|
|
|
|
crm_log_args(argc, argv);
|
|
@@ -1628,15 +1629,15 @@ main(int argc, char **argv)
|
|
goto done;
|
|
}
|
|
|
|
- // Sanity check validating from command line parameters. If everything checks out,
|
|
- // go ahead and run the validation. This way we don't need a CIB connection.
|
|
- if (options.validate_cmdline) {
|
|
- validate_cmdline(&exit_code);
|
|
- goto done;
|
|
- } else if (options.validate_options != NULL) {
|
|
+ if (options.cmdline_config) {
|
|
+ /* A resource configuration was given on the command line. Sanity-check
|
|
+ * the values and set error if they don't make sense.
|
|
+ */
|
|
+ validate_cmdline_config();
|
|
+ } else if (options.cmdline_params != NULL) {
|
|
// @COMPAT @TODO error out here when we can break backward compatibility
|
|
- g_hash_table_destroy(options.validate_options);
|
|
- options.validate_options = NULL;
|
|
+ g_hash_table_destroy(options.cmdline_params);
|
|
+ options.cmdline_params = NULL;
|
|
}
|
|
|
|
if (error != NULL) {
|
|
@@ -1773,12 +1774,18 @@ main(int argc, char **argv)
|
|
break;
|
|
|
|
case cmd_execute_agent:
|
|
- exit_code = cli_resource_execute(out, rsc, options.rsc_id,
|
|
- options.operation,
|
|
- options.override_params,
|
|
- options.timeout_ms, cib_conn,
|
|
- data_set, options.resource_verbose,
|
|
- options.force);
|
|
+ if (options.cmdline_config) {
|
|
+ exit_code = cli_resource_execute_from_params(out, "test",
|
|
+ options.v_class, options.v_provider, options.v_agent,
|
|
+ "validate-all", options.cmdline_params,
|
|
+ options.override_params, options.timeout_ms,
|
|
+ args->verbosity, options.force);
|
|
+ } else {
|
|
+ exit_code = cli_resource_execute(out, rsc, options.rsc_id,
|
|
+ options.operation, options.override_params,
|
|
+ options.timeout_ms, cib_conn, data_set,
|
|
+ args->verbosity, options.force);
|
|
+ }
|
|
break;
|
|
|
|
case cmd_colocations:
|
|
@@ -2038,7 +2045,7 @@ done:
|
|
g_hash_table_destroy(options.override_params);
|
|
}
|
|
|
|
- /* options.validate_options does not need to be destroyed here. See the
|
|
+ /* options.cmdline_params does not need to be destroyed here. See the
|
|
* comments in cli_resource_execute_from_params.
|
|
*/
|
|
|
|
--
|
|
1.8.3.1
|
|
|
|
|
|
From e140bd1bc35a20f027f054b4575808bd0ef547fc Mon Sep 17 00:00:00 2001
|
|
From: Ken Gaillot <kgaillot@redhat.com>
|
|
Date: Wed, 16 Sep 2020 15:40:16 -0500
|
|
Subject: [PATCH 2/6] Low: tools: handle required node names better in
|
|
crm_resource
|
|
|
|
Currently, --fail is the only option that requires a node name to be specified,
|
|
but generalize the handling so future options can reuse it.
|
|
|
|
This also makes the error handling closer to what's done for required resource
|
|
names, both in error message and exit status.
|
|
---
|
|
tools/crm_resource.c | 87 ++++++++++++++++++++++++++++----------------
|
|
tools/crm_resource_runtime.c | 8 +---
|
|
2 files changed, 57 insertions(+), 38 deletions(-)
|
|
|
|
diff --git a/tools/crm_resource.c b/tools/crm_resource.c
|
|
index 1dcb0f0..2717a62 100644
|
|
--- a/tools/crm_resource.c
|
|
+++ b/tools/crm_resource.c
|
|
@@ -74,6 +74,7 @@ struct {
|
|
gboolean require_crmd; // Whether command requires controller IPC
|
|
gboolean require_dataset; // Whether command requires populated data set
|
|
gboolean require_resource; // Whether command requires resource specified
|
|
+ gboolean require_node; // Whether command requires node specified
|
|
int find_flags; // Flags to use when searching for resource
|
|
|
|
// Command-line option values
|
|
@@ -774,6 +775,7 @@ option_cb(const gchar *option_name, const gchar *optarg, gpointer data,
|
|
gboolean
|
|
fail_cb(const gchar *option_name, const gchar *optarg, gpointer data, GError **error) {
|
|
options.require_crmd = TRUE;
|
|
+ options.require_node = TRUE;
|
|
SET_COMMAND(cmd_fail);
|
|
return TRUE;
|
|
}
|
|
@@ -1483,9 +1485,13 @@ main(int argc, char **argv)
|
|
{
|
|
xmlNode *cib_xml_copy = NULL;
|
|
pe_resource_t *rsc = NULL;
|
|
-
|
|
+ pe_node_t *node = NULL;
|
|
int rc = pcmk_rc_ok;
|
|
|
|
+ /*
|
|
+ * Parse command line arguments
|
|
+ */
|
|
+
|
|
pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY);
|
|
GOptionContext *context = NULL;
|
|
GOptionGroup *output_group = NULL;
|
|
@@ -1502,6 +1508,10 @@ main(int argc, char **argv)
|
|
goto done;
|
|
}
|
|
|
|
+ /*
|
|
+ * Set verbosity
|
|
+ */
|
|
+
|
|
for (int i = 0; i < args->verbosity; i++) {
|
|
crm_bump_log_level(argc, argv);
|
|
}
|
|
@@ -1518,9 +1528,9 @@ main(int argc, char **argv)
|
|
|
|
crm_log_args(argc, argv);
|
|
|
|
- if (options.host_uname) {
|
|
- crm_trace("Option host => %s", options.host_uname);
|
|
- }
|
|
+ /*
|
|
+ * Validate option combinations
|
|
+ */
|
|
|
|
// If the user didn't explicitly specify a command, list resources
|
|
if (options.rsc_cmd == cmd_none) {
|
|
@@ -1634,30 +1644,42 @@ main(int argc, char **argv)
|
|
* the values and set error if they don't make sense.
|
|
*/
|
|
validate_cmdline_config();
|
|
+ if (error != NULL) {
|
|
+ exit_code = CRM_EX_USAGE;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
} else if (options.cmdline_params != NULL) {
|
|
// @COMPAT @TODO error out here when we can break backward compatibility
|
|
g_hash_table_destroy(options.cmdline_params);
|
|
options.cmdline_params = NULL;
|
|
}
|
|
|
|
- if (error != NULL) {
|
|
+ if (options.require_resource && (options.rsc_id == NULL)) {
|
|
+ rc = ENXIO;
|
|
+ exit_code = CRM_EX_USAGE;
|
|
+ g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
|
|
+ "Must supply a resource id with -r");
|
|
+ goto done;
|
|
+ }
|
|
+ if (options.require_node && (options.host_uname == NULL)) {
|
|
+ rc = ENXIO;
|
|
exit_code = CRM_EX_USAGE;
|
|
+ g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
|
|
+ "Must supply a node name with -N");
|
|
goto done;
|
|
}
|
|
|
|
+ /*
|
|
+ * Set up necessary connections
|
|
+ */
|
|
+
|
|
if (options.force) {
|
|
crm_debug("Forcing...");
|
|
cib__set_call_options(options.cib_options, crm_system_name,
|
|
cib_quorum_override);
|
|
}
|
|
|
|
- if (options.require_resource && !options.rsc_id) {
|
|
- rc = ENXIO;
|
|
- g_set_error(&error, PCMK__EXITC_ERROR, CRM_EX_USAGE,
|
|
- "Must supply a resource id with -r");
|
|
- goto done;
|
|
- }
|
|
-
|
|
if (options.find_flags && options.rsc_id) {
|
|
options.require_dataset = TRUE;
|
|
}
|
|
@@ -1700,6 +1722,11 @@ main(int argc, char **argv)
|
|
}
|
|
}
|
|
|
|
+ // If user supplied a node name, check whether it exists
|
|
+ if ((options.host_uname != NULL) && (data_set != NULL)) {
|
|
+ node = pe_find_node(data_set->nodes, options.host_uname);
|
|
+ }
|
|
+
|
|
// Establish a connection to the controller if needed
|
|
if (options.require_crmd) {
|
|
rc = pcmk_new_ipc_api(&controld_api, pcmk_ipc_controld);
|
|
@@ -1718,6 +1745,10 @@ main(int argc, char **argv)
|
|
}
|
|
}
|
|
|
|
+ /*
|
|
+ * Handle requested command
|
|
+ */
|
|
+
|
|
switch (options.rsc_cmd) {
|
|
case cmd_list_resources: {
|
|
GListPtr all = NULL;
|
|
@@ -1844,18 +1875,11 @@ main(int argc, char **argv)
|
|
break;
|
|
|
|
case cmd_why:
|
|
- {
|
|
- pe_node_t *dest = NULL;
|
|
-
|
|
- if (options.host_uname) {
|
|
- dest = pe_find_node(data_set->nodes, options.host_uname);
|
|
- if (dest == NULL) {
|
|
- rc = pcmk_rc_node_unknown;
|
|
- goto done;
|
|
- }
|
|
- }
|
|
- out->message(out, "resource-reasons-list", cib_conn, data_set->resources, rsc, dest);
|
|
- rc = pcmk_rc_ok;
|
|
+ if ((options.host_uname != NULL) && (node == NULL)) {
|
|
+ rc = pcmk_rc_node_unknown;
|
|
+ } else {
|
|
+ rc = out->message(out, "resource-reasons-list", cib_conn,
|
|
+ data_set->resources, rsc, node);
|
|
}
|
|
break;
|
|
|
|
@@ -1878,15 +1902,10 @@ main(int argc, char **argv)
|
|
case cmd_ban:
|
|
if (options.host_uname == NULL) {
|
|
rc = ban_or_move(out, rsc, options.move_lifetime, &exit_code);
|
|
+ } else if (node == NULL) {
|
|
+ rc = pcmk_rc_node_unknown;
|
|
} else {
|
|
- pe_node_t *dest = pe_find_node(data_set->nodes,
|
|
- options.host_uname);
|
|
-
|
|
- if (dest == NULL) {
|
|
- rc = pcmk_rc_node_unknown;
|
|
- goto done;
|
|
- }
|
|
- rc = cli_resource_ban(out, options.rsc_id, dest->details->uname,
|
|
+ rc = cli_resource_ban(out, options.rsc_id, node->details->uname,
|
|
options.move_lifetime, NULL, cib_conn,
|
|
options.cib_options,
|
|
options.promoted_role_only);
|
|
@@ -2002,6 +2021,10 @@ main(int argc, char **argv)
|
|
break;
|
|
}
|
|
|
|
+ /*
|
|
+ * Clean up and exit
|
|
+ */
|
|
+
|
|
done:
|
|
if (rc != pcmk_rc_ok) {
|
|
if (rc == pcmk_rc_no_quorum) {
|
|
diff --git a/tools/crm_resource_runtime.c b/tools/crm_resource_runtime.c
|
|
index 3f28c7b..de5e807 100644
|
|
--- a/tools/crm_resource_runtime.c
|
|
+++ b/tools/crm_resource_runtime.c
|
|
@@ -1,5 +1,5 @@
|
|
/*
|
|
- * Copyright 2004-2020 the Pacemaker project contributors
|
|
+ * Copyright 2004-2021 the Pacemaker project contributors
|
|
*
|
|
* The version control history for this file may have further details.
|
|
*
|
|
@@ -511,11 +511,7 @@ send_lrm_rsc_op(pcmk__output_t *out, pcmk_ipc_api_t *controld_api, bool do_fail_
|
|
return EINVAL;
|
|
}
|
|
|
|
- if (host_uname == NULL) {
|
|
- out->err(out, "Please specify a node name");
|
|
- return EINVAL;
|
|
-
|
|
- } else {
|
|
+ {
|
|
pe_node_t *node = pe_find_node(data_set->nodes, host_uname);
|
|
|
|
if (node == NULL) {
|
|
--
|
|
1.8.3.1
|
|
|
|
|
|
From 31bda91470487790d6e17b6f2cbed282bafd11d0 Mon Sep 17 00:00:00 2001
|
|
From: Ken Gaillot <kgaillot@redhat.com>
|
|
Date: Tue, 15 Sep 2020 15:00:53 -0500
|
|
Subject: [PATCH 3/6] Refactor: libpacemaker: add files for resource-related
|
|
API
|
|
|
|
---
|
|
include/pacemaker-internal.h | 3 ++-
|
|
include/pcmki/Makefile.am | 3 ++-
|
|
include/pcmki/pcmki_resource.h | 14 ++++++++++++++
|
|
lib/pacemaker/Makefile.am | 3 ++-
|
|
lib/pacemaker/pcmk_resource.c | 21 +++++++++++++++++++++
|
|
5 files changed, 41 insertions(+), 3 deletions(-)
|
|
create mode 100644 include/pcmki/pcmki_resource.h
|
|
create mode 100644 lib/pacemaker/pcmk_resource.c
|
|
|
|
diff --git a/include/pacemaker-internal.h b/include/pacemaker-internal.h
|
|
index 2e75d09..bf33f3e 100644
|
|
--- a/include/pacemaker-internal.h
|
|
+++ b/include/pacemaker-internal.h
|
|
@@ -1,5 +1,5 @@
|
|
/*
|
|
- * Copyright 2019 the Pacemaker project contributors
|
|
+ * Copyright 2019-2021 the Pacemaker project contributors
|
|
*
|
|
* The version control history for this file may have further details.
|
|
*
|
|
@@ -14,6 +14,7 @@
|
|
# include <pcmki/pcmki_cluster_queries.h>
|
|
# include <pcmki/pcmki_fence.h>
|
|
# include <pcmki/pcmki_output.h>
|
|
+# include <pcmki/pcmki_resource.h>
|
|
# include <pcmki/pcmki_sched_allocate.h>
|
|
# include <pcmki/pcmki_sched_notif.h>
|
|
# include <pcmki/pcmki_sched_utils.h>
|
|
diff --git a/include/pcmki/Makefile.am b/include/pcmki/Makefile.am
|
|
index 7aa64c7..446c801 100644
|
|
--- a/include/pcmki/Makefile.am
|
|
+++ b/include/pcmki/Makefile.am
|
|
@@ -1,5 +1,5 @@
|
|
#
|
|
-# Copyright 2019 the Pacemaker project contributors
|
|
+# Copyright 2019-2021 the Pacemaker project contributors
|
|
#
|
|
# The version control history for this file may have further details.
|
|
#
|
|
@@ -13,6 +13,7 @@ noinst_HEADERS = pcmki_error.h \
|
|
pcmki_cluster_queries.h \
|
|
pcmki_fence.h \
|
|
pcmki_output.h \
|
|
+ pcmki_resource.h \
|
|
pcmki_sched_allocate.h \
|
|
pcmki_sched_notif.h \
|
|
pcmki_sched_utils.h \
|
|
diff --git a/include/pcmki/pcmki_resource.h b/include/pcmki/pcmki_resource.h
|
|
new file mode 100644
|
|
index 0000000..effa945
|
|
--- /dev/null
|
|
+++ b/include/pcmki/pcmki_resource.h
|
|
@@ -0,0 +1,14 @@
|
|
+/*
|
|
+ * Copyright 2021 the Pacemaker project contributors
|
|
+ *
|
|
+ * The version control history for this file may have further details.
|
|
+ *
|
|
+ * This source code is licensed under the GNU Lesser General Public License
|
|
+ * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
|
|
+ */
|
|
+#ifndef PCMKI_RESOURCE__H
|
|
+#define PCMKI_RESOURCE__H
|
|
+
|
|
+#include <crm/common/output_internal.h>
|
|
+
|
|
+#endif /* PCMK_RESOURCE__H */
|
|
diff --git a/lib/pacemaker/Makefile.am b/lib/pacemaker/Makefile.am
|
|
index 4129ade..760c04a 100644
|
|
--- a/lib/pacemaker/Makefile.am
|
|
+++ b/lib/pacemaker/Makefile.am
|
|
@@ -1,5 +1,5 @@
|
|
#
|
|
-# Copyright 2004-2019 the Pacemaker project contributors
|
|
+# Copyright 2004-2021 the Pacemaker project contributors
|
|
#
|
|
# The version control history for this file may have further details.
|
|
#
|
|
@@ -31,6 +31,7 @@ libpacemaker_la_SOURCES =
|
|
libpacemaker_la_SOURCES += pcmk_cluster_queries.c
|
|
libpacemaker_la_SOURCES += pcmk_fence.c
|
|
libpacemaker_la_SOURCES += pcmk_output.c
|
|
+libpacemaker_la_SOURCES += pcmk_resource.c
|
|
libpacemaker_la_SOURCES += pcmk_sched_allocate.c
|
|
libpacemaker_la_SOURCES += pcmk_sched_bundle.c
|
|
libpacemaker_la_SOURCES += pcmk_sched_clone.c
|
|
diff --git a/lib/pacemaker/pcmk_resource.c b/lib/pacemaker/pcmk_resource.c
|
|
new file mode 100644
|
|
index 0000000..05614fc
|
|
--- /dev/null
|
|
+++ b/lib/pacemaker/pcmk_resource.c
|
|
@@ -0,0 +1,21 @@
|
|
+/*
|
|
+ * Copyright 2021 the Pacemaker project contributors
|
|
+ *
|
|
+ * The version control history for this file may have further details.
|
|
+ *
|
|
+ * This source code is licensed under the GNU General Public License version 2
|
|
+ * or later (GPLv2+) WITHOUT ANY WARRANTY.
|
|
+ */
|
|
+
|
|
+#include <crm_internal.h>
|
|
+
|
|
+#include <glib.h>
|
|
+#include <libxml/tree.h>
|
|
+
|
|
+#include <crm/common/mainloop.h>
|
|
+#include <crm/common/results.h>
|
|
+#include <crm/common/output_internal.h>
|
|
+#include <crm/pengine/internal.h>
|
|
+
|
|
+#include <pacemaker.h>
|
|
+#include <pacemaker-internal.h>
|
|
--
|
|
1.8.3.1
|
|
|
|
|
|
From e45fe95cc6f526ab67ab6f718aa1364861ca525b Mon Sep 17 00:00:00 2001
|
|
From: Ken Gaillot <kgaillot@redhat.com>
|
|
Date: Tue, 15 Sep 2020 15:32:25 -0500
|
|
Subject: [PATCH 4/6] API: libpacemaker: new API pcmk_resource_digests()
|
|
|
|
---
|
|
include/pacemaker.h | 22 +++++++-
|
|
include/pcmki/pcmki_resource.h | 7 +++
|
|
lib/pacemaker/pcmk_output.c | 107 +++++++++++++++++++++++++++++++++++-
|
|
lib/pacemaker/pcmk_resource.c | 119 +++++++++++++++++++++++++++++++++++++++++
|
|
xml/Makefile.am | 10 +++-
|
|
xml/api/digests-2.6.rng | 33 ++++++++++++
|
|
6 files changed, 293 insertions(+), 5 deletions(-)
|
|
create mode 100644 xml/api/digests-2.6.rng
|
|
|
|
diff --git a/include/pacemaker.h b/include/pacemaker.h
|
|
index b2a73cd..51bf585 100644
|
|
--- a/include/pacemaker.h
|
|
+++ b/include/pacemaker.h
|
|
@@ -1,5 +1,5 @@
|
|
/*
|
|
- * Copyright 2019 the Pacemaker project contributors
|
|
+ * Copyright 2019-2021 the Pacemaker project contributors
|
|
*
|
|
* The version control history for this file may have further details.
|
|
*
|
|
@@ -20,8 +20,11 @@ extern "C" {
|
|
* \ingroup pacemaker
|
|
*/
|
|
|
|
-# include <crm/stonith-ng.h>
|
|
+# include <glib.h>
|
|
# include <libxml/tree.h>
|
|
+# include <crm/pengine/pe_types.h>
|
|
+
|
|
+# include <crm/stonith-ng.h>
|
|
|
|
/*!
|
|
* \brief Get controller status
|
|
@@ -55,6 +58,21 @@ int pcmk_designated_controller(xmlNodePtr *xml, unsigned int message_timeout_ms)
|
|
*/
|
|
int pcmk_pacemakerd_status(xmlNodePtr *xml, char *ipc_name, unsigned int message_timeout_ms);
|
|
|
|
+/*!
|
|
+ * \brief Calculate and output resource operation digests
|
|
+ *
|
|
+ * \param[out] xml Where to store XML with result
|
|
+ * \param[in] rsc Resource to calculate digests for
|
|
+ * \param[in] node Node whose operation history should be used
|
|
+ * \param[in] overrides Hash table of configuration parameters to override
|
|
+ * \param[in] data_set Cluster working set (with status)
|
|
+ *
|
|
+ * \return Standard Pacemaker return code
|
|
+ */
|
|
+int pcmk_resource_digests(xmlNodePtr *xml, pe_resource_t *rsc,
|
|
+ pe_node_t *node, GHashTable *overrides,
|
|
+ pe_working_set_t *data_set);
|
|
+
|
|
#ifdef BUILD_PUBLIC_LIBPACEMAKER
|
|
|
|
/*!
|
|
diff --git a/include/pcmki/pcmki_resource.h b/include/pcmki/pcmki_resource.h
|
|
index effa945..9d2afb5 100644
|
|
--- a/include/pcmki/pcmki_resource.h
|
|
+++ b/include/pcmki/pcmki_resource.h
|
|
@@ -9,6 +9,13 @@
|
|
#ifndef PCMKI_RESOURCE__H
|
|
#define PCMKI_RESOURCE__H
|
|
|
|
+#include <glib.h>
|
|
+
|
|
#include <crm/common/output_internal.h>
|
|
+#include <crm/pengine/pe_types.h>
|
|
+
|
|
+int pcmk__resource_digests(pcmk__output_t *out, pe_resource_t *rsc,
|
|
+ pe_node_t *node, GHashTable *overrides,
|
|
+ pe_working_set_t *data_set);
|
|
|
|
#endif /* PCMK_RESOURCE__H */
|
|
diff --git a/lib/pacemaker/pcmk_output.c b/lib/pacemaker/pcmk_output.c
|
|
index 500afd1..bc4b91a 100644
|
|
--- a/lib/pacemaker/pcmk_output.c
|
|
+++ b/lib/pacemaker/pcmk_output.c
|
|
@@ -1,5 +1,5 @@
|
|
/*
|
|
- * Copyright 2019-2020 the Pacemaker project contributors
|
|
+ * Copyright 2019-2021 the Pacemaker project contributors
|
|
*
|
|
* The version control history for this file may have further details.
|
|
*
|
|
@@ -12,6 +12,7 @@
|
|
#include <crm/common/output_internal.h>
|
|
#include <crm/stonith-ng.h>
|
|
#include <crm/fencing/internal.h>
|
|
+#include <crm/pengine/internal.h>
|
|
#include <libxml/tree.h>
|
|
#include <pacemaker-internal.h>
|
|
|
|
@@ -539,6 +540,108 @@ crmadmin_node_xml(pcmk__output_t *out, va_list args)
|
|
return pcmk_rc_ok;
|
|
}
|
|
|
|
+PCMK__OUTPUT_ARGS("digests", "pe_resource_t *", "pe_node_t *", "const char *",
|
|
+ "guint", "op_digest_cache_t *")
|
|
+static int
|
|
+digests_text(pcmk__output_t *out, va_list args)
|
|
+{
|
|
+ pe_resource_t *rsc = va_arg(args, pe_resource_t *);
|
|
+ pe_node_t *node = va_arg(args, pe_node_t *);
|
|
+ const char *task = va_arg(args, const char *);
|
|
+ guint interval_ms = va_arg(args, guint);
|
|
+ op_digest_cache_t *digests = va_arg(args, op_digest_cache_t *);
|
|
+
|
|
+ char *action_desc = NULL;
|
|
+ const char *rsc_desc = "unknown resource";
|
|
+ const char *node_desc = "unknown node";
|
|
+
|
|
+ if (interval_ms != 0) {
|
|
+ action_desc = crm_strdup_printf("%ums-interval %s action", interval_ms,
|
|
+ ((task == NULL)? "unknown" : task));
|
|
+ } else if (pcmk__str_eq(task, "monitor", pcmk__str_none)) {
|
|
+ action_desc = strdup("probe action");
|
|
+ } else {
|
|
+ action_desc = crm_strdup_printf("%s action",
|
|
+ ((task == NULL)? "unknown" : task));
|
|
+ }
|
|
+ if ((rsc != NULL) && (rsc->id != NULL)) {
|
|
+ rsc_desc = rsc->id;
|
|
+ }
|
|
+ if ((node != NULL) && (node->details->uname != NULL)) {
|
|
+ node_desc = node->details->uname;
|
|
+ }
|
|
+ out->begin_list(out, NULL, NULL, "Digests for %s %s on %s",
|
|
+ rsc_desc, action_desc, node_desc);
|
|
+ free(action_desc);
|
|
+
|
|
+ if (digests == NULL) {
|
|
+ out->list_item(out, NULL, "none");
|
|
+ out->end_list(out);
|
|
+ return pcmk_rc_ok;
|
|
+ }
|
|
+ if (digests->digest_all_calc != NULL) {
|
|
+ out->list_item(out, NULL, "%s (all parameters)",
|
|
+ digests->digest_all_calc);
|
|
+ }
|
|
+ if (digests->digest_secure_calc != NULL) {
|
|
+ out->list_item(out, NULL, "%s (non-private parameters)",
|
|
+ digests->digest_secure_calc);
|
|
+ }
|
|
+ if (digests->digest_restart_calc != NULL) {
|
|
+ out->list_item(out, NULL, "%s (non-reloadable parameters)",
|
|
+ digests->digest_restart_calc);
|
|
+ }
|
|
+ out->end_list(out);
|
|
+ return pcmk_rc_ok;
|
|
+}
|
|
+
|
|
+static void
|
|
+add_digest_xml(xmlNode *parent, const char *type, const char *digest,
|
|
+ xmlNode *digest_source)
|
|
+{
|
|
+ if (digest != NULL) {
|
|
+ xmlNodePtr digest_xml = create_xml_node(parent, "digest");
|
|
+
|
|
+ crm_xml_add(digest_xml, "type", ((type == NULL)? "unspecified" : type));
|
|
+ crm_xml_add(digest_xml, "hash", digest);
|
|
+ if (digest_source != NULL) {
|
|
+ add_node_copy(digest_xml, digest_source);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+PCMK__OUTPUT_ARGS("digests", "pe_resource_t *", "pe_node_t *", "const char *",
|
|
+ "guint", "op_digest_cache_t *")
|
|
+static int
|
|
+digests_xml(pcmk__output_t *out, va_list args)
|
|
+{
|
|
+ pe_resource_t *rsc = va_arg(args, pe_resource_t *);
|
|
+ pe_node_t *node = va_arg(args, pe_node_t *);
|
|
+ const char *task = va_arg(args, const char *);
|
|
+ guint interval_ms = va_arg(args, guint);
|
|
+ op_digest_cache_t *digests = va_arg(args, op_digest_cache_t *);
|
|
+
|
|
+ char *interval_s = crm_strdup_printf("%ums", interval_ms);
|
|
+ xmlNode *xml = NULL;
|
|
+
|
|
+ xml = pcmk__output_create_xml_node(out, "digests",
|
|
+ "resource", crm_str(rsc->id),
|
|
+ "node", crm_str(node->details->uname),
|
|
+ "task", crm_str(task),
|
|
+ "interval", interval_s,
|
|
+ NULL);
|
|
+ free(interval_s);
|
|
+ if (digests != NULL) {
|
|
+ add_digest_xml(xml, "all", digests->digest_all_calc,
|
|
+ digests->params_all);
|
|
+ add_digest_xml(xml, "nonprivate", digests->digest_secure_calc,
|
|
+ digests->params_secure);
|
|
+ add_digest_xml(xml, "nonreloadable", digests->digest_restart_calc,
|
|
+ digests->params_restart);
|
|
+ }
|
|
+ return pcmk_rc_ok;
|
|
+}
|
|
+
|
|
static pcmk__message_entry_t fmt_functions[] = {
|
|
{ "rsc-is-colocated-with-list", "default", rsc_is_colocated_with_list },
|
|
{ "rsc-is-colocated-with-list", "xml", rsc_is_colocated_with_list_xml },
|
|
@@ -557,6 +660,8 @@ static pcmk__message_entry_t fmt_functions[] = {
|
|
{ "crmadmin-node-list", "default", crmadmin_node_list },
|
|
{ "crmadmin-node", "default", crmadmin_node_text },
|
|
{ "crmadmin-node", "xml", crmadmin_node_xml },
|
|
+ { "digests", "default", digests_text },
|
|
+ { "digests", "xml", digests_xml },
|
|
|
|
{ NULL, NULL, NULL }
|
|
};
|
|
diff --git a/lib/pacemaker/pcmk_resource.c b/lib/pacemaker/pcmk_resource.c
|
|
index 05614fc..197edf8 100644
|
|
--- a/lib/pacemaker/pcmk_resource.c
|
|
+++ b/lib/pacemaker/pcmk_resource.c
|
|
@@ -9,6 +9,7 @@
|
|
|
|
#include <crm_internal.h>
|
|
|
|
+#include <errno.h>
|
|
#include <glib.h>
|
|
#include <libxml/tree.h>
|
|
|
|
@@ -19,3 +20,121 @@
|
|
|
|
#include <pacemaker.h>
|
|
#include <pacemaker-internal.h>
|
|
+
|
|
+// Search path for resource operation history (takes node name and resource ID)
|
|
+#define XPATH_OP_HISTORY "//" XML_CIB_TAG_STATUS \
|
|
+ "/" XML_CIB_TAG_STATE "[@" XML_ATTR_UNAME "='%s']" \
|
|
+ "/" XML_CIB_TAG_LRM "/" XML_LRM_TAG_RESOURCES \
|
|
+ "/" XML_LRM_TAG_RESOURCE "[@" XML_ATTR_ID "='%s']"
|
|
+
|
|
+static xmlNode *
|
|
+best_op(pe_resource_t *rsc, pe_node_t *node, pe_working_set_t *data_set)
|
|
+{
|
|
+ char *xpath = NULL;
|
|
+ xmlNode *history = NULL;
|
|
+ xmlNode *best = NULL;
|
|
+
|
|
+ // Find node's resource history
|
|
+ xpath = crm_strdup_printf(XPATH_OP_HISTORY, node->details->uname, rsc->id);
|
|
+ history = get_xpath_object(xpath, data_set->input, LOG_NEVER);
|
|
+ free(xpath);
|
|
+
|
|
+ // Examine each history entry
|
|
+ for (xmlNode *lrm_rsc_op = first_named_child(history, XML_LRM_TAG_RSC_OP);
|
|
+ lrm_rsc_op != NULL; lrm_rsc_op = crm_next_same_xml(lrm_rsc_op)) {
|
|
+
|
|
+ const char *digest = crm_element_value(lrm_rsc_op,
|
|
+ XML_LRM_ATTR_RESTART_DIGEST);
|
|
+ guint interval_ms = 0;
|
|
+
|
|
+ crm_element_value_ms(lrm_rsc_op, XML_LRM_ATTR_INTERVAL, &interval_ms);
|
|
+
|
|
+ if (pcmk__ends_with(ID(lrm_rsc_op), "_last_failure_0")
|
|
+ || (interval_ms != 0)) {
|
|
+
|
|
+ // Only use last failure or recurring op if nothing else available
|
|
+ if (best == NULL) {
|
|
+ best = lrm_rsc_op;
|
|
+ }
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ best = lrm_rsc_op;
|
|
+ if (digest != NULL) {
|
|
+ // Any non-recurring action with a restart digest is sufficient
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ return best;
|
|
+}
|
|
+
|
|
+/*!
|
|
+ * \internal
|
|
+ * \brief Calculate and output resource operation digests
|
|
+ *
|
|
+ * \param[in] out Output object
|
|
+ * \param[in] rsc Resource to calculate digests for
|
|
+ * \param[in] node Node whose operation history should be used
|
|
+ * \param[in] overrides Hash table of configuration parameters to override
|
|
+ * \param[in] data_set Cluster working set (with status)
|
|
+ *
|
|
+ * \return Standard Pacemaker return code
|
|
+ */
|
|
+int
|
|
+pcmk__resource_digests(pcmk__output_t *out, pe_resource_t *rsc,
|
|
+ pe_node_t *node, GHashTable *overrides,
|
|
+ pe_working_set_t *data_set)
|
|
+{
|
|
+ const char *task = NULL;
|
|
+ xmlNode *xml_op = NULL;
|
|
+ op_digest_cache_t *digests = NULL;
|
|
+ guint interval_ms = 0;
|
|
+ int rc = pcmk_rc_ok;
|
|
+
|
|
+ if ((out == NULL) || (rsc == NULL) || (node == NULL) || (data_set == NULL)) {
|
|
+ return EINVAL;
|
|
+ }
|
|
+ if (rsc->variant != pe_native) {
|
|
+ // Only primitives get operation digests
|
|
+ return EOPNOTSUPP;
|
|
+ }
|
|
+
|
|
+ // Find XML of operation history to use
|
|
+ xml_op = best_op(rsc, node, data_set);
|
|
+
|
|
+ // Generate an operation key
|
|
+ if (xml_op != NULL) {
|
|
+ task = crm_element_value(xml_op, XML_LRM_ATTR_TASK);
|
|
+ crm_element_value_ms(xml_op, XML_LRM_ATTR_INTERVAL_MS, &interval_ms);
|
|
+ }
|
|
+ if (task == NULL) { // Assume start if no history is available
|
|
+ task = RSC_START;
|
|
+ interval_ms = 0;
|
|
+ }
|
|
+
|
|
+ // Calculate and show digests
|
|
+ digests = pe__calculate_digests(rsc, task, &interval_ms, node, xml_op,
|
|
+ overrides, true, data_set);
|
|
+ rc = out->message(out, "digests", rsc, node, task, interval_ms, digests);
|
|
+
|
|
+ pe__free_digests(digests);
|
|
+ return rc;
|
|
+}
|
|
+
|
|
+int
|
|
+pcmk_resource_digests(xmlNodePtr *xml, pe_resource_t *rsc,
|
|
+ pe_node_t *node, GHashTable *overrides,
|
|
+ pe_working_set_t *data_set)
|
|
+{
|
|
+ pcmk__output_t *out = NULL;
|
|
+ int rc = pcmk_rc_ok;
|
|
+
|
|
+ rc = pcmk__out_prologue(&out, xml);
|
|
+ if (rc != pcmk_rc_ok) {
|
|
+ return rc;
|
|
+ }
|
|
+ pcmk__register_lib_messages(out);
|
|
+ rc = pcmk__resource_digests(out, rsc, node, overrides, data_set);
|
|
+ pcmk__out_epilogue(out, xml, rc);
|
|
+ return rc;
|
|
+}
|
|
diff --git a/xml/Makefile.am b/xml/Makefile.am
|
|
index e7b9a51..cb6cfa0 100644
|
|
--- a/xml/Makefile.am
|
|
+++ b/xml/Makefile.am
|
|
@@ -1,5 +1,5 @@
|
|
#
|
|
-# Copyright 2004-2019 the Pacemaker project contributors
|
|
+# Copyright 2004-2021 the Pacemaker project contributors
|
|
#
|
|
# The version control history for this file may have further details.
|
|
#
|
|
@@ -50,7 +50,13 @@ version_pairs_last = $(wordlist \
|
|
# problems.
|
|
|
|
# Names of API schemas that form the choices for pacemaker-result content
|
|
-API_request_base = command-output crm_mon crm_resource crmadmin stonith_admin version
|
|
+API_request_base = command-output \
|
|
+ crm_mon \
|
|
+ crm_resource \
|
|
+ crmadmin \
|
|
+ digests \
|
|
+ stonith_admin \
|
|
+ version
|
|
|
|
# Names of CIB schemas that form the choices for cib/configuration content
|
|
CIB_cfg_base = options nodes resources constraints fencing acls tags alerts
|
|
diff --git a/xml/api/digests-2.6.rng b/xml/api/digests-2.6.rng
|
|
new file mode 100644
|
|
index 0000000..7e843d4
|
|
--- /dev/null
|
|
+++ b/xml/api/digests-2.6.rng
|
|
@@ -0,0 +1,33 @@
|
|
+<?xml version="1.0" encoding="UTF-8"?>
|
|
+<grammar xmlns="http://relaxng.org/ns/structure/1.0"
|
|
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
|
|
+
|
|
+ <start>
|
|
+ <ref name="element-digests"/>
|
|
+ </start>
|
|
+
|
|
+ <define name="element-digests">
|
|
+ <attribute name="resource"> <text/> </attribute>
|
|
+ <attribute name="node"> <text/> </attribute>
|
|
+ <attribute name="task"> <text/> </attribute>
|
|
+ <attribute name="interval"> <text/> </attribute>
|
|
+ <zeroOrMore>
|
|
+ <ref name="element-digest"/>
|
|
+ </zeroOrMore>
|
|
+ </define>
|
|
+
|
|
+ <define name="element-digest">
|
|
+ <attribute name="type"> <text/> </attribute>
|
|
+ <attribute name="hash"> <text/> </attribute>
|
|
+ <optional>
|
|
+ <element name="parameters">
|
|
+ <zeroOrMore>
|
|
+ <attribute>
|
|
+ <anyName/>
|
|
+ <text/>
|
|
+ </attribute>
|
|
+ </zeroOrMore>
|
|
+ </element>
|
|
+ </optional>
|
|
+ </define>
|
|
+</grammar>
|
|
--
|
|
1.8.3.1
|
|
|
|
|
|
From 4e726eb67c8eed255ee83706ed13cd7ea31f9864 Mon Sep 17 00:00:00 2001
|
|
From: Ken Gaillot <kgaillot@redhat.com>
|
|
Date: Mon, 14 Sep 2020 16:29:41 -0500
|
|
Subject: [PATCH 5/6] Feature: tools: add crm_resource --digests option
|
|
|
|
This is not particularly useful for end users but can help during development,
|
|
and can be used by higher-level tools to bypass Pacemaker's configuration
|
|
change detection (with obvious risks).
|
|
---
|
|
tools/crm_resource.c | 39 ++++++++++++++++++++++++++++++++++++++-
|
|
1 file changed, 38 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/tools/crm_resource.c b/tools/crm_resource.c
|
|
index 2717a62..8c7247a 100644
|
|
--- a/tools/crm_resource.c
|
|
+++ b/tools/crm_resource.c
|
|
@@ -40,6 +40,7 @@ enum rsc_command {
|
|
cmd_cts,
|
|
cmd_delete,
|
|
cmd_delete_param,
|
|
+ cmd_digests,
|
|
cmd_execute_agent,
|
|
cmd_fail,
|
|
cmd_get_param,
|
|
@@ -158,6 +159,8 @@ gboolean validate_or_force_cb(const gchar *option_name, const gchar *optarg,
|
|
gpointer data, GError **error);
|
|
gboolean restart_cb(const gchar *option_name, const gchar *optarg,
|
|
gpointer data, GError **error);
|
|
+gboolean digests_cb(const gchar *option_name, const gchar *optarg,
|
|
+ gpointer data, GError **error);
|
|
gboolean wait_cb(const gchar *option_name, const gchar *optarg, gpointer data, GError **error);
|
|
gboolean why_cb(const gchar *option_name, const gchar *optarg, gpointer data, GError **error);
|
|
|
|
@@ -507,6 +510,14 @@ static GOptionEntry advanced_entries[] = {
|
|
{ "wait", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, wait_cb,
|
|
"(Advanced) Wait until the cluster settles into a stable state",
|
|
NULL },
|
|
+ { "digests", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, digests_cb,
|
|
+ "(Advanced) Show parameter hashes that Pacemaker uses to detect\n"
|
|
+ INDENT "configuration changes (only accurate if there is resource\n"
|
|
+ INDENT "history on the specified node). Required: --resource, --node.\n"
|
|
+ INDENT "Optional: any NAME=VALUE parameters will be used to override\n"
|
|
+ INDENT "the configuration (to see what the hash would be with those\n"
|
|
+ INDENT "changes).",
|
|
+ NULL },
|
|
{ "force-demote", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
|
|
validate_or_force_cb,
|
|
"(Advanced) Bypass the cluster and demote a resource on the local\n"
|
|
@@ -893,7 +904,9 @@ validate_or_force_cb(const gchar *option_name, const gchar *optarg,
|
|
}
|
|
options.operation = g_strdup(option_name + 2); // skip "--"
|
|
options.find_flags = pe_find_renamed|pe_find_anon;
|
|
- options.override_params = crm_str_table_new();
|
|
+ if (options.override_params == NULL) {
|
|
+ options.override_params = crm_str_table_new();
|
|
+ }
|
|
return TRUE;
|
|
}
|
|
|
|
@@ -907,6 +920,20 @@ restart_cb(const gchar *option_name, const gchar *optarg, gpointer data,
|
|
}
|
|
|
|
gboolean
|
|
+digests_cb(const gchar *option_name, const gchar *optarg, gpointer data,
|
|
+ GError **error)
|
|
+{
|
|
+ SET_COMMAND(cmd_digests);
|
|
+ options.find_flags = pe_find_renamed|pe_find_anon;
|
|
+ if (options.override_params == NULL) {
|
|
+ options.override_params = crm_str_table_new();
|
|
+ }
|
|
+ options.require_node = TRUE;
|
|
+ options.require_dataset = TRUE;
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+gboolean
|
|
wait_cb(const gchar *option_name, const gchar *optarg, gpointer data, GError **error) {
|
|
SET_COMMAND(cmd_wait);
|
|
options.require_resource = FALSE;
|
|
@@ -1819,6 +1846,16 @@ main(int argc, char **argv)
|
|
}
|
|
break;
|
|
|
|
+ case cmd_digests:
|
|
+ node = pe_find_node(data_set->nodes, options.host_uname);
|
|
+ if (node == NULL) {
|
|
+ rc = pcmk_rc_node_unknown;
|
|
+ } else {
|
|
+ rc = pcmk__resource_digests(out, rsc, node,
|
|
+ options.override_params, data_set);
|
|
+ }
|
|
+ break;
|
|
+
|
|
case cmd_colocations:
|
|
rc = out->message(out, "stacks-constraints", rsc, data_set, false);
|
|
break;
|
|
--
|
|
1.8.3.1
|
|
|
|
|
|
From bb34d07013bed2e71ac9cedb4b1631ad5e2825bf Mon Sep 17 00:00:00 2001
|
|
From: Ken Gaillot <kgaillot@redhat.com>
|
|
Date: Mon, 23 Nov 2020 12:17:31 -0600
|
|
Subject: [PATCH 6/6] Test: cts-cli: add regression tests for crm_resource
|
|
--digests
|
|
|
|
---
|
|
cts/Makefile.am | 3 +-
|
|
cts/cli/crm_resource_digests.xml | 143 +++++++++++++++++++++++++++++++++++++++
|
|
cts/cli/regression.tools.exp | 34 ++++++++++
|
|
cts/cts-cli.in | 14 +++-
|
|
4 files changed, 192 insertions(+), 2 deletions(-)
|
|
create mode 100644 cts/cli/crm_resource_digests.xml
|
|
|
|
diff --git a/cts/Makefile.am b/cts/Makefile.am
|
|
index 5666a9f..de02aed 100644
|
|
--- a/cts/Makefile.am
|
|
+++ b/cts/Makefile.am
|
|
@@ -1,5 +1,5 @@
|
|
#
|
|
-# Copyright 2001-2019 the Pacemaker project contributors
|
|
+# Copyright 2001-2021 the Pacemaker project contributors
|
|
#
|
|
# The version control history for this file may have further details.
|
|
#
|
|
@@ -65,6 +65,7 @@ dist_cli_DATA = cli/constraints.xml \
|
|
cli/crm_diff_old.xml \
|
|
cli/crm_mon.xml \
|
|
cli/crm_mon-partial.xml \
|
|
+ cli/crm_resource_digests.xml \
|
|
cli/regression.acls.exp \
|
|
cli/regression.crm_mon.exp \
|
|
cli/regression.dates.exp \
|
|
diff --git a/cts/cli/crm_resource_digests.xml b/cts/cli/crm_resource_digests.xml
|
|
new file mode 100644
|
|
index 0000000..074ca3d
|
|
--- /dev/null
|
|
+++ b/cts/cli/crm_resource_digests.xml
|
|
@@ -0,0 +1,143 @@
|
|
+<cib crm_feature_set="3.6.3" validate-with="pacemaker-3.0" epoch="253" num_updates="20" admin_epoch="0" cib-last-written="Sun Nov 22 14:45:16 2020" update-origin="node2" update-client="cibadmin" update-user="root" have-quorum="1" dc-uuid="1">
|
|
+ <configuration>
|
|
+ <crm_config>
|
|
+ <cluster_property_set id="cib-bootstrap-options">
|
|
+ <nvpair id="cts-stonith-enabled" name="stonith-enabled" value="1"/>
|
|
+ <nvpair id="cib-bootstrap-options-have-watchdog" name="have-watchdog" value="false"/>
|
|
+ <nvpair id="cib-bootstrap-options-dc-version" name="dc-version" value="2.0.5"/>
|
|
+ <nvpair id="cib-bootstrap-options-cluster-infrastructure" name="cluster-infrastructure" value="corosync"/>
|
|
+ </cluster_property_set>
|
|
+ </crm_config>
|
|
+ <nodes>
|
|
+ <node id="1" uname="node1"/>
|
|
+ <node id="2" uname="node2"/>
|
|
+ <node id="3" uname="node3"/>
|
|
+ <node id="4" uname="node4"/>
|
|
+ <node id="5" uname="node5"/>
|
|
+ </nodes>
|
|
+ <resources>
|
|
+ <primitive class="stonith" id="Fencing" type="fence_xvm">
|
|
+ <meta_attributes id="Fencing-meta">
|
|
+ <nvpair id="Fencing-migration-threshold" name="migration-threshold" value="5"/>
|
|
+ </meta_attributes>
|
|
+ <instance_attributes id="Fencing-params">
|
|
+ <nvpair id="Fencing-key_file" name="key_file" value="/etc/pacemaker/fence_xvm.key"/>
|
|
+ <nvpair id="Fencing-multicast_address" name="multicast_address" value="239.255.100.100"/>
|
|
+ <nvpair id="Fencing-pcmk_host_list" name="pcmk_host_list" value="node1 node2 node3 node4 node5"/>
|
|
+ </instance_attributes>
|
|
+ <operations>
|
|
+ <op id="Fencing-monitor-120s" interval="120s" name="monitor" timeout="120s"/>
|
|
+ <op id="Fencing-stop-0" interval="0" name="stop" timeout="60s"/>
|
|
+ <op id="Fencing-start-0" interval="0" name="start" timeout="60s"/>
|
|
+ </operations>
|
|
+ </primitive>
|
|
+ <primitive class="ocf" id="rsc1" provider="pacemaker" type="Dummy">
|
|
+ <instance_attributes id="rsc1-instance_attributes">
|
|
+ <nvpair id="rsc1-instance_attributes-fake" name="fake" value="1"/>
|
|
+ <nvpair id="rsc1-instance_attributes-passwd" name="passwd" value="secret"/>
|
|
+ </instance_attributes>
|
|
+ <instance_attributes id="rsc1-instance_attributes-node1">
|
|
+ <nvpair id="rsc1-instance_attributes-fake-node1" name="fake" value="0"/>
|
|
+ <rule id="rsc1-rule1" score="INFINITY">
|
|
+ <expression attribute="#uname" id="rsc1-rule1-expr1" operation="eq" value="node1"/>
|
|
+ </rule>
|
|
+ </instance_attributes>
|
|
+ <operations>
|
|
+ <op id="rsc1-migrate_from-interval-0s" interval="0s" name="migrate_from" timeout="20s"/>
|
|
+ <op id="rsc1-migrate_to-interval-0s" interval="0s" name="migrate_to" timeout="20s"/>
|
|
+ <op id="rsc1-monitor-interval-10s" interval="10s" name="monitor" timeout="20s"/>
|
|
+ <op id="rsc1-reload-interval-0s" interval="0s" name="reload" timeout="20s"/>
|
|
+ <op id="rsc1-start-interval-0s" interval="0s" name="start" timeout="20s"/>
|
|
+ <op id="rsc1-stop-interval-0s" interval="0s" name="stop" timeout="20s"/>
|
|
+ </operations>
|
|
+ </primitive>
|
|
+ </resources>
|
|
+ <constraints>
|
|
+ <rsc_location id="location-rsc1-node1-INFINITY" node="node1" rsc="rsc1" score="INFINITY"/>
|
|
+ </constraints>
|
|
+ <fencing-topology/>
|
|
+ <op_defaults/>
|
|
+ <alerts/>
|
|
+ <rsc_defaults/>
|
|
+ </configuration>
|
|
+ <status>
|
|
+ <node_state id="4" uname="node4" in_ccm="true" crmd="online" crm-debug-origin="do_state_transition" join="member" expected="member">
|
|
+ <transient_attributes id="4">
|
|
+ <instance_attributes id="status-4"/>
|
|
+ </transient_attributes>
|
|
+ <lrm id="4">
|
|
+ <lrm_resources>
|
|
+ <lrm_resource id="rsc1" type="Dummy" class="ocf" provider="pacemaker">
|
|
+ <lrm_rsc_op id="rsc1_last_0" operation_key="rsc1_monitor_0" operation="monitor" crm-debug-origin="build_active_RAs" crm_feature_set="3.6.3" transition-key="5:51:7:727e4004-8c04-423b-8d63-65ae1fabd119" transition-magic="0:7;5:51:7:727e4004-8c04-423b-8d63-65ae1fabd119" exit-reason="" on_node="node4" call-id="136" rc-code="7" op-status="0" interval="0" last-rc-change="1606076573" last-run="1606076573" exec-time="28" queue-time="0" op-digest="2b1b5ccbabbdb96f3f7edb41b0775563" op-force-restart=" envfile op_sleep passwd state " op-restart-digest="f2317cad3d54cec5d7d7aa7d0bf35cf8" op-secure-params=" passwd " op-secure-digest="2b1b5ccbabbdb96f3f7edb41b0775563"/>
|
|
+ </lrm_resource>
|
|
+ <lrm_resource id="Fencing" type="fence_xvm" class="stonith">
|
|
+ <lrm_rsc_op id="Fencing_last_0" operation_key="Fencing_monitor_0" operation="monitor" crm-debug-origin="build_active_RAs" crm_feature_set="3.6.3" transition-key="43:0:7:727e4004-8c04-423b-8d63-65ae1fabd119" transition-magic="0:7;43:0:7:727e4004-8c04-423b-8d63-65ae1fabd119" exit-reason="" on_node="node4" call-id="5" rc-code="7" op-status="0" interval="0" last-rc-change="1606076227" last-run="1606076227" exec-time="2" queue-time="0" op-digest="52e34745a77d95a636428d3b550eb867"/>
|
|
+ </lrm_resource>
|
|
+ </lrm_resources>
|
|
+ </lrm>
|
|
+ </node_state>
|
|
+ <node_state id="2" uname="node2" in_ccm="true" crmd="online" crm-debug-origin="do_state_transition" join="member" expected="member">
|
|
+ <transient_attributes id="2">
|
|
+ <instance_attributes id="status-2"/>
|
|
+ </transient_attributes>
|
|
+ <lrm id="2">
|
|
+ <lrm_resources>
|
|
+ <lrm_resource id="rsc1" type="Dummy" class="ocf" provider="pacemaker">
|
|
+ <lrm_rsc_op id="rsc1_last_0" operation_key="rsc1_monitor_0" operation="monitor" crm-debug-origin="build_active_RAs" crm_feature_set="3.6.3" transition-key="3:51:7:727e4004-8c04-423b-8d63-65ae1fabd119" transition-magic="0:7;3:51:7:727e4004-8c04-423b-8d63-65ae1fabd119" exit-reason="" on_node="node2" call-id="101" rc-code="7" op-status="0" interval="0" last-rc-change="1606076573" last-run="1606076573" exec-time="45" queue-time="0" op-digest="2b1b5ccbabbdb96f3f7edb41b0775563" op-force-restart=" envfile op_sleep passwd state " op-restart-digest="f2317cad3d54cec5d7d7aa7d0bf35cf8" op-secure-params=" passwd " op-secure-digest="2b1b5ccbabbdb96f3f7edb41b0775563"/>
|
|
+ </lrm_resource>
|
|
+ <lrm_resource id="Fencing" type="fence_xvm" class="stonith">
|
|
+ <lrm_rsc_op id="Fencing_last_0" operation_key="Fencing_monitor_0" operation="monitor" crm-debug-origin="build_active_RAs" crm_feature_set="3.6.3" transition-key="15:0:7:727e4004-8c04-423b-8d63-65ae1fabd119" transition-magic="0:7;15:0:7:727e4004-8c04-423b-8d63-65ae1fabd119" exit-reason="" on_node="node2" call-id="5" rc-code="7" op-status="0" interval="0" last-rc-change="1606076227" last-run="1606076227" exec-time="4" queue-time="0" op-digest="52e34745a77d95a636428d3b550eb867"/>
|
|
+ </lrm_resource>
|
|
+ </lrm_resources>
|
|
+ </lrm>
|
|
+ </node_state>
|
|
+ <node_state id="3" uname="node3" in_ccm="true" crmd="online" crm-debug-origin="do_update_resource" join="member" expected="member">
|
|
+ <transient_attributes id="3">
|
|
+ <instance_attributes id="status-3"/>
|
|
+ </transient_attributes>
|
|
+ <lrm id="3">
|
|
+ <lrm_resources>
|
|
+ <lrm_resource id="rsc1" type="Dummy" class="ocf" provider="pacemaker">
|
|
+ <lrm_rsc_op id="rsc1_last_0" operation_key="rsc1_stop_0" operation="stop" crm-debug-origin="do_update_resource" crm_feature_set="3.6.3" transition-key="7:55:0:727e4004-8c04-423b-8d63-65ae1fabd119" transition-magic="0:0;7:55:0:727e4004-8c04-423b-8d63-65ae1fabd119" exit-reason="" on_node="node3" call-id="121" rc-code="0" op-status="0" interval="0" last-rc-change="1606077916" last-run="1606077916" exec-time="26" queue-time="0" op-digest="c18bfacc816dc3a5a53f23c000e6e57e" op-force-restart=" envfile op_sleep passwd state " op-restart-digest="5de1fd72a2e7762ed41543231034f6d7" op-secure-params=" passwd " op-secure-digest="2b1b5ccbabbdb96f3f7edb41b0775563"/>
|
|
+ <lrm_rsc_op id="rsc1_monitor_10000" operation_key="rsc1_monitor_10000" operation="monitor" crm-debug-origin="build_active_RAs" crm_feature_set="3.6.3" transition-key="1:52:0:727e4004-8c04-423b-8d63-65ae1fabd119" transition-magic="0:0;1:52:0:727e4004-8c04-423b-8d63-65ae1fabd119" exit-reason="" on_node="node3" call-id="118" rc-code="0" op-status="0" interval="10000" last-rc-change="1606076598" exec-time="20" queue-time="0" op-digest="0b73673404cb867681a3c190ccebcc51" op-secure-params=" passwd " op-secure-digest="2b1b5ccbabbdb96f3f7edb41b0775563"/>
|
|
+ </lrm_resource>
|
|
+ <lrm_resource id="Fencing" type="fence_xvm" class="stonith">
|
|
+ <lrm_rsc_op id="Fencing_last_0" operation_key="Fencing_monitor_0" operation="monitor" crm-debug-origin="build_active_RAs" crm_feature_set="3.6.3" transition-key="29:0:7:727e4004-8c04-423b-8d63-65ae1fabd119" transition-magic="0:7;29:0:7:727e4004-8c04-423b-8d63-65ae1fabd119" exit-reason="" on_node="node3" call-id="5" rc-code="7" op-status="0" interval="0" last-rc-change="1606076227" last-run="1606076227" exec-time="24" queue-time="0" op-digest="52e34745a77d95a636428d3b550eb867"/>
|
|
+ </lrm_resource>
|
|
+ </lrm_resources>
|
|
+ </lrm>
|
|
+ </node_state>
|
|
+ <node_state id="5" uname="node5" in_ccm="true" crmd="online" crm-debug-origin="do_state_transition" join="member" expected="member">
|
|
+ <transient_attributes id="5">
|
|
+ <instance_attributes id="status-5"/>
|
|
+ </transient_attributes>
|
|
+ <lrm id="5">
|
|
+ <lrm_resources>
|
|
+ <lrm_resource id="rsc1" type="Dummy" class="ocf" provider="pacemaker">
|
|
+ <lrm_rsc_op id="rsc1_last_0" operation_key="rsc1_monitor_0" operation="monitor" crm-debug-origin="build_active_RAs" crm_feature_set="3.6.3" transition-key="6:51:7:727e4004-8c04-423b-8d63-65ae1fabd119" transition-magic="0:7;6:51:7:727e4004-8c04-423b-8d63-65ae1fabd119" exit-reason="" on_node="node5" call-id="99" rc-code="7" op-status="0" interval="0" last-rc-change="1606076573" last-run="1606076573" exec-time="27" queue-time="0" op-digest="2b1b5ccbabbdb96f3f7edb41b0775563" op-force-restart=" envfile op_sleep passwd state " op-restart-digest="f2317cad3d54cec5d7d7aa7d0bf35cf8" op-secure-params=" passwd " op-secure-digest="2b1b5ccbabbdb96f3f7edb41b0775563"/>
|
|
+ </lrm_resource>
|
|
+ <lrm_resource id="Fencing" type="fence_xvm" class="stonith">
|
|
+ <lrm_rsc_op id="Fencing_last_0" operation_key="Fencing_monitor_0" operation="monitor" crm-debug-origin="build_active_RAs" crm_feature_set="3.6.3" transition-key="57:0:7:727e4004-8c04-423b-8d63-65ae1fabd119" transition-magic="0:7;57:0:7:727e4004-8c04-423b-8d63-65ae1fabd119" exit-reason="" on_node="node5" call-id="5" rc-code="7" op-status="0" interval="0" last-rc-change="1606076227" last-run="1606076227" exec-time="14" queue-time="0" op-digest="52e34745a77d95a636428d3b550eb867"/>
|
|
+ </lrm_resource>
|
|
+ </lrm_resources>
|
|
+ </lrm>
|
|
+ </node_state>
|
|
+ <node_state id="1" uname="node1" in_ccm="true" crmd="online" crm-debug-origin="do_update_resource" join="member" expected="member">
|
|
+ <transient_attributes id="1">
|
|
+ <instance_attributes id="status-1"/>
|
|
+ </transient_attributes>
|
|
+ <lrm id="1">
|
|
+ <lrm_resources>
|
|
+ <lrm_resource id="rsc1" type="Dummy" class="ocf" provider="pacemaker">
|
|
+ <lrm_rsc_op id="rsc1_last_0" operation_key="rsc1_start_0" operation="start" crm-debug-origin="do_update_resource" crm_feature_set="3.6.3" transition-key="8:55:0:727e4004-8c04-423b-8d63-65ae1fabd119" transition-magic="0:0;8:55:0:727e4004-8c04-423b-8d63-65ae1fabd119" exit-reason="" on_node="node1" call-id="104" rc-code="0" op-status="0" interval="0" last-rc-change="1606077916" last-run="1606077916" exec-time="22" queue-time="0" op-digest="3acdbe4c12734ebeb1251a59545af936" op-force-restart=" envfile op_sleep passwd state " op-restart-digest="5de1fd72a2e7762ed41543231034f6d7" op-secure-params=" passwd " op-secure-digest="279c477dbc38c621904a00ab9e599b2f"/>
|
|
+ <lrm_rsc_op id="rsc1_monitor_10000" operation_key="rsc1_monitor_10000" operation="monitor" crm-debug-origin="do_update_resource" crm_feature_set="3.6.3" transition-key="9:55:0:727e4004-8c04-423b-8d63-65ae1fabd119" transition-magic="0:0;9:55:0:727e4004-8c04-423b-8d63-65ae1fabd119" exit-reason="" on_node="node1" call-id="106" rc-code="0" op-status="0" interval="10000" last-rc-change="1606077916" exec-time="20" queue-time="0" op-digest="720718e8d715d5d3be1403cbbcb953bc" op-secure-params=" passwd " op-secure-digest="279c477dbc38c621904a00ab9e599b2f"/>
|
|
+ </lrm_resource>
|
|
+ <lrm_resource id="Fencing" type="fence_xvm" class="stonith">
|
|
+ <lrm_rsc_op id="Fencing_last_0" operation_key="Fencing_start_0" operation="start" crm-debug-origin="build_active_RAs" crm_feature_set="3.6.3" transition-key="71:0:0:727e4004-8c04-423b-8d63-65ae1fabd119" transition-magic="0:0;71:0:0:727e4004-8c04-423b-8d63-65ae1fabd119" exit-reason="" on_node="node1" call-id="10" rc-code="0" op-status="0" interval="0" last-rc-change="1606076227" last-run="1606076227" exec-time="59" queue-time="0" op-digest="52e34745a77d95a636428d3b550eb867"/>
|
|
+ <lrm_rsc_op id="Fencing_monitor_120000" operation_key="Fencing_monitor_120000" operation="monitor" crm-debug-origin="build_active_RAs" crm_feature_set="3.6.3" transition-key="72:0:0:727e4004-8c04-423b-8d63-65ae1fabd119" transition-magic="0:0;72:0:0:727e4004-8c04-423b-8d63-65ae1fabd119" exit-reason="" on_node="node1" call-id="12" rc-code="0" op-status="0" interval="120000" last-rc-change="1606076227" exec-time="70" queue-time="0" op-digest="acc6dd2c58c637db4d12a6fe35626617"/>
|
|
+ </lrm_resource>
|
|
+ </lrm_resources>
|
|
+ </lrm>
|
|
+ </node_state>
|
|
+ </status>
|
|
+</cib>
|
|
diff --git a/cts/cli/regression.tools.exp b/cts/cli/regression.tools.exp
|
|
index a85b7d6..510cc0a 100644
|
|
--- a/cts/cli/regression.tools.exp
|
|
+++ b/cts/cli/regression.tools.exp
|
|
@@ -4019,3 +4019,37 @@ Resources colocated with clone:
|
|
</pacemaker-result>
|
|
=#=#=#= End test: Recursively check locations and constraints for clone in XML - OK (0) =#=#=#=
|
|
* Passed: crm_resource - Recursively check locations and constraints for clone in XML
|
|
+=#=#=#= Begin test: Show resource digests =#=#=#=
|
|
+<pacemaker-result api-version="X" request="crm_resource --digests -r rsc1 -N node1 --output-as=xml">
|
|
+ <digests resource="rsc1" node="node1" task="start" interval="0ms">
|
|
+ <digest type="all" hash="3acdbe4c12734ebeb1251a59545af936">
|
|
+ <parameters passwd="secret" fake="0"/>
|
|
+ </digest>
|
|
+ <digest type="nonprivate" hash="279c477dbc38c621904a00ab9e599b2f">
|
|
+ <parameters fake="0"/>
|
|
+ </digest>
|
|
+ <digest type="nonreloadable" hash="5de1fd72a2e7762ed41543231034f6d7">
|
|
+ <parameters passwd="secret"/>
|
|
+ </digest>
|
|
+ </digests>
|
|
+ <status code="0" message="OK"/>
|
|
+</pacemaker-result>
|
|
+=#=#=#= End test: Show resource digests - OK (0) =#=#=#=
|
|
+* Passed: crm_resource - Show resource digests
|
|
+=#=#=#= Begin test: Show resource digests with overrides =#=#=#=
|
|
+<pacemaker-result api-version="X" request="crm_resource --digests -r rsc1 -N node1 --output-as=xml CRM_meta_interval=10000 CRM_meta_timeout=20000">
|
|
+ <digests resource="rsc1" node="node1" task="start" interval="10000ms">
|
|
+ <digest type="all" hash="720718e8d715d5d3be1403cbbcb953bc">
|
|
+ <parameters passwd="secret" fake="0" CRM_meta_timeout="20000"/>
|
|
+ </digest>
|
|
+ <digest type="nonprivate" hash="279c477dbc38c621904a00ab9e599b2f">
|
|
+ <parameters fake="0"/>
|
|
+ </digest>
|
|
+ <digest type="nonreloadable" hash="5de1fd72a2e7762ed41543231034f6d7">
|
|
+ <parameters passwd="secret"/>
|
|
+ </digest>
|
|
+ </digests>
|
|
+ <status code="0" message="OK"/>
|
|
+</pacemaker-result>
|
|
+=#=#=#= End test: Show resource digests with overrides - OK (0) =#=#=#=
|
|
+* Passed: crm_resource - Show resource digests with overrides
|
|
diff --git a/cts/cts-cli.in b/cts/cts-cli.in
|
|
index dfdd3de..96f5386 100755
|
|
--- a/cts/cts-cli.in
|
|
+++ b/cts/cts-cli.in
|
|
@@ -1,6 +1,6 @@
|
|
#!@BASH_PATH@
|
|
#
|
|
-# Copyright 2008-2020 the Pacemaker project contributors
|
|
+# Copyright 2008-2021 the Pacemaker project contributors
|
|
#
|
|
# The version control history for this file may have further details.
|
|
#
|
|
@@ -791,6 +791,18 @@ function test_tools() {
|
|
done
|
|
|
|
unset CIB_file
|
|
+
|
|
+ export CIB_file="$test_home/cli/crm_resource_digests.xml"
|
|
+
|
|
+ desc="Show resource digests"
|
|
+ cmd="crm_resource --digests -r rsc1 -N node1 --output-as=xml"
|
|
+ test_assert $CRM_EX_OK 0
|
|
+
|
|
+ desc="Show resource digests with overrides"
|
|
+ cmd="$cmd CRM_meta_interval=10000 CRM_meta_timeout=20000"
|
|
+ test_assert $CRM_EX_OK 0
|
|
+
|
|
+ unset CIB_file
|
|
}
|
|
|
|
INVALID_PERIODS=(
|
|
--
|
|
1.8.3.1
|
|
|