From a5a507d4e1abf242903472719a19977811e6f164 Mon Sep 17 00:00:00 2001 From: Chris Lumens Date: Thu, 20 May 2021 11:59:36 -0400 Subject: [PATCH 01/10] Feature: libcrmcommon: Add OCF_OUTPUT_FORMAT to crm_resource environment. See: rhbz#1644628 --- lib/common/output.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/common/output.c b/lib/common/output.c index 6cb49b5..58872e0 100644 --- a/lib/common/output.c +++ b/lib/common/output.c @@ -71,6 +71,8 @@ pcmk__output_new(pcmk__output_t **out, const char *fmt_name, const char *filenam return ENOMEM; } + setenv("OCF_OUTPUT_FORMAT", (*out)->fmt_name, 1); + return pcmk_rc_ok; } -- 1.8.3.1 From acc6ecdbfb797d69794e68f75a734d6252434e01 Mon Sep 17 00:00:00 2001 From: Chris Lumens Date: Fri, 21 May 2021 14:20:30 -0400 Subject: [PATCH 02/10] Feature: schemas: Copy crm_resource schema in preparation for changes. See: rhbz#1644628 --- xml/api/crm_resource-2.11.rng | 238 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 xml/api/crm_resource-2.11.rng diff --git a/xml/api/crm_resource-2.11.rng b/xml/api/crm_resource-2.11.rng new file mode 100644 index 0000000..8e386db --- /dev/null +++ b/xml/api/crm_resource-2.11.rng @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + promoted + + + + + + + + + + + + + + + + + + + + + + + + + + + ocf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + false + + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Stopped + Started + Master + Slave + + + -- 1.8.3.1 From 1bbdf2149a111e9e19c388834f82001e0d31c427 Mon Sep 17 00:00:00 2001 From: Chris Lumens Date: Mon, 24 May 2021 12:23:55 -0400 Subject: [PATCH 03/10] Feature: xml: Update the crm_resource schema for XML output. See: rhbz#1644628 --- xml/api/crm_resource-2.11.rng | 50 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/xml/api/crm_resource-2.11.rng b/xml/api/crm_resource-2.11.rng index 8e386db..aaa54d6 100644 --- a/xml/api/crm_resource-2.11.rng +++ b/xml/api/crm_resource-2.11.rng @@ -20,6 +20,7 @@ + @@ -227,6 +228,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Stopped -- 1.8.3.1 From d89f5bc7fec856fdcd32fa14edbd0019507d5d15 Mon Sep 17 00:00:00 2001 From: Chris Lumens Date: Tue, 1 Jun 2021 15:26:58 -0400 Subject: [PATCH 04/10] Low: libcrmcommon: Increase PCMK__API_VERSION for new crm_resource output. See: rhbz#1644628 --- include/crm/common/output_internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/crm/common/output_internal.h b/include/crm/common/output_internal.h index 10b315b..0436cde 100644 --- a/include/crm/common/output_internal.h +++ b/include/crm/common/output_internal.h @@ -27,7 +27,7 @@ extern "C" { # include # include -# define PCMK__API_VERSION "2.9" +# define PCMK__API_VERSION "2.11" #if defined(PCMK__WITH_ATTRIBUTE_OUTPUT_ARGS) # define PCMK__OUTPUT_ARGS(ARGS...) __attribute__((output_args(ARGS))) -- 1.8.3.1 From 30bd2ddf43ee2a911681e51f40ed9ba20ec250b0 Mon Sep 17 00:00:00 2001 From: Chris Lumens Date: Thu, 27 May 2021 13:57:12 -0400 Subject: [PATCH 05/10] Low: tools: Pass NULL to cli_resource_execute_from_params... if no resource name is given. This happens if we are validating based on the --class/--agent/--provider command line options instead. --- tools/crm_resource.c | 2 +- tools/crm_resource_runtime.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/crm_resource.c b/tools/crm_resource.c index 24f1121..37a0bb0 100644 --- a/tools/crm_resource.c +++ b/tools/crm_resource.c @@ -1840,7 +1840,7 @@ main(int argc, char **argv) case cmd_execute_agent: if (options.cmdline_config) { - exit_code = cli_resource_execute_from_params(out, "test", + exit_code = cli_resource_execute_from_params(out, NULL, options.v_class, options.v_provider, options.v_agent, "validate-all", options.cmdline_params, options.override_params, options.timeout_ms, diff --git a/tools/crm_resource_runtime.c b/tools/crm_resource_runtime.c index 48a4b40..ebf48bb 100644 --- a/tools/crm_resource_runtime.c +++ b/tools/crm_resource_runtime.c @@ -1717,14 +1717,14 @@ cli_resource_execute_from_params(pcmk__output_t *out, const char *rsc_name, */ params_copy = pcmk__str_table_dup(params); - op = resources_action_create(rsc_name, rsc_class, rsc_prov, rsc_type, action, 0, - timeout_ms, params_copy, 0); + op = resources_action_create(rsc_name ? rsc_name : "test", rsc_class, rsc_prov, + rsc_type, action, 0, timeout_ms, params_copy, 0); if (op == NULL) { /* Re-run with stderr enabled so we can display a sane error message */ crm_enable_stderr(TRUE); params_copy = pcmk__str_table_dup(params); - op = resources_action_create(rsc_name, rsc_class, rsc_prov, rsc_type, action, 0, - timeout_ms, params_copy, 0); + op = resources_action_create(rsc_name ? rsc_name : "test", rsc_class, rsc_prov, + rsc_type, action, 0, timeout_ms, params_copy, 0); /* Callers of cli_resource_execute expect that the params hash table will * be freed. That function uses this one, so for that reason and for -- 1.8.3.1 From ee56efd53d14cfc4f902769540b72b3bb6096a73 Mon Sep 17 00:00:00 2001 From: Chris Lumens Date: Mon, 24 May 2021 12:08:52 -0400 Subject: [PATCH 06/10] Feature: tools: Add an agent-status message for crm_resource. This moves what was previously only done in an out->info call to its own output message, which means it will appear in XML output as well. Also, note that if --class/--agent/--provider are given, the resource name will be set to "test". In that case, do not display the resource name in the output. This message will be used for --validate and the --force-* command line options to crm_resource. See: rhbz#1644628 --- tools/crm_resource_print.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/tools/crm_resource_print.c b/tools/crm_resource_print.c index 9d82cf8..88d5878 100644 --- a/tools/crm_resource_print.c +++ b/tools/crm_resource_print.c @@ -152,6 +152,57 @@ attribute_list_default(pcmk__output_t *out, va_list args) { return pcmk_rc_ok; } +PCMK__OUTPUT_ARGS("agent-status", "int", "const char *", "const char *", "const char *", + "const char *", "const char *", "int") +static int +agent_status_default(pcmk__output_t *out, va_list args) { + int status = va_arg(args, int); + const char *action = va_arg(args, const char *); + const char *name = va_arg(args, const char *); + const char *class = va_arg(args, const char *); + const char *provider = va_arg(args, const char *); + const char *type = va_arg(args, const char *); + int rc = va_arg(args, int); + + if (status == PCMK_LRM_OP_DONE) { + out->info(out, "Operation %s%s%s (%s%s%s:%s) returned: '%s' (%d)", + action, name ? " for " : "", name ? name : "", + class, provider ? ":" : "", provider ? provider : "", type, + services_ocf_exitcode_str(rc), rc); + } else { + out->err(out, "Operation %s%s%s (%s%s%s:%s) failed: '%s' (%d)", + action, name ? " for " : "", name ? name : "", + class, provider ? ":" : "", provider ? provider : "", type, + services_lrm_status_str(status), status); + } + + return pcmk_rc_ok; +} + +PCMK__OUTPUT_ARGS("agent-status", "int", "const char *", "const char *", "const char *", + "const char *", "const char *", "int") +static int +agent_status_xml(pcmk__output_t *out, va_list args) { + int status G_GNUC_UNUSED = va_arg(args, int); + const char *action G_GNUC_UNUSED = va_arg(args, const char *); + const char *name G_GNUC_UNUSED = va_arg(args, const char *); + const char *class G_GNUC_UNUSED = va_arg(args, const char *); + const char *provider G_GNUC_UNUSED = va_arg(args, const char *); + const char *type G_GNUC_UNUSED = va_arg(args, const char *); + int rc = va_arg(args, int); + + char *status_str = pcmk__itoa(rc); + + pcmk__output_create_xml_node(out, "agent-status", + "code", status_str, + "message", services_ocf_exitcode_str(rc), + NULL); + + free(status_str); + + return pcmk_rc_ok; +} + PCMK__OUTPUT_ARGS("attribute-list", "pe_resource_t *", "char *", "GHashTable *") static int attribute_list_text(pcmk__output_t *out, va_list args) { @@ -562,6 +613,8 @@ resource_names(pcmk__output_t *out, va_list args) { } static pcmk__message_entry_t fmt_functions[] = { + { "agent-status", "default", agent_status_default }, + { "agent-status", "xml", agent_status_xml }, { "attribute-list", "default", attribute_list_default }, { "attribute-list", "text", attribute_list_text }, { "property-list", "default", property_list_default }, -- 1.8.3.1 From 85cb6b6bff96b18c5174d11e4de4d49cbfb20bb7 Mon Sep 17 00:00:00 2001 From: Chris Lumens Date: Tue, 1 Jun 2021 14:47:30 -0400 Subject: [PATCH 07/10] Feature: tools: Add an overridden params output message. This also replaces what was previously being done in an out->info call with an output message. This means it shows up in XML output as well. Also, note that if --class/--agent/--provider are given, the resource name will be set to "test". In that case, do not display the resource name in the output. See: rhbz#1644628 --- tools/crm_resource_print.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/tools/crm_resource_print.c b/tools/crm_resource_print.c index 88d5878..119d83f 100644 --- a/tools/crm_resource_print.c +++ b/tools/crm_resource_print.c @@ -224,6 +224,43 @@ attribute_list_text(pcmk__output_t *out, va_list args) { return pcmk_rc_ok; } +PCMK__OUTPUT_ARGS("override", "const char *", "const char *", "const char *") +static int +override_default(pcmk__output_t *out, va_list args) { + const char *rsc_name = va_arg(args, const char *); + const char *name = va_arg(args, const char *); + const char *value = va_arg(args, const char *); + + if (rsc_name == NULL) { + out->list_item(out, NULL, "Overriding the cluster configuration with '%s' = '%s'", + name, value); + } else { + out->list_item(out, NULL, "Overriding the cluster configuration for '%s' with '%s' = '%s'", + rsc_name, name, value); + } + + return pcmk_rc_ok; +} + +PCMK__OUTPUT_ARGS("override", "const char *", "const char *", "const char *") +static int +override_xml(pcmk__output_t *out, va_list args) { + const char *rsc_name = va_arg(args, const char *); + const char *name = va_arg(args, const char *); + const char *value = va_arg(args, const char *); + + xmlNodePtr node = pcmk__output_create_xml_node(out, "override", + "name", name, + "value", value, + NULL); + + if (rsc_name != NULL) { + crm_xml_add(node, "rsc", rsc_name); + } + + return pcmk_rc_ok; +} + PCMK__OUTPUT_ARGS("property-list", "pe_resource_t *", "char *") static int property_list_default(pcmk__output_t *out, va_list args) { @@ -617,6 +654,8 @@ static pcmk__message_entry_t fmt_functions[] = { { "agent-status", "xml", agent_status_xml }, { "attribute-list", "default", attribute_list_default }, { "attribute-list", "text", attribute_list_text }, + { "override", "default", override_default }, + { "override", "xml", override_xml }, { "property-list", "default", property_list_default }, { "property-list", "text", property_list_text }, { "resource-check-list", "default", resource_check_list_default }, -- 1.8.3.1 From e5e24592c7c3231c619fb5253e7925ffbc634a99 Mon Sep 17 00:00:00 2001 From: Chris Lumens Date: Fri, 4 Jun 2021 10:24:51 -0400 Subject: [PATCH 08/10] Low: tools: Use simple XML lists for resource actions as well. See: rhbz#1644628 --- tools/crm_resource.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/crm_resource.c b/tools/crm_resource.c index 37a0bb0..e957011 100644 --- a/tools/crm_resource.c +++ b/tools/crm_resource.c @@ -1643,6 +1643,7 @@ main(int argc, char **argv) * saves from having to write custom messages to build the lists around all these things */ switch (options.rsc_cmd) { + case cmd_execute_agent: case cmd_list_resources: case cmd_query_xml: case cmd_query_raw_xml: -- 1.8.3.1 From 3e75174d0bc31b261adb1994214a5878b79da85b Mon Sep 17 00:00:00 2001 From: Chris Lumens Date: Fri, 4 Jun 2021 10:30:10 -0400 Subject: [PATCH 09/10] Feature: tools: Add an output message for resource actions. This wraps up the override and agent-status messages into a single message, along with any stdout/stderr from the resource action. This message should be called after taking the action. This also implements handling XML output from resource actions. Check to see if the validate-all action returns XML. If so, output it as a CDATA block under a "command" element. If not, treat it as plain text and output it as stdout/stderr from a command. See: rhbz#1644628 --- tools/crm_resource_print.c | 122 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) diff --git a/tools/crm_resource_print.c b/tools/crm_resource_print.c index 119d83f..19a366d 100644 --- a/tools/crm_resource_print.c +++ b/tools/crm_resource_print.c @@ -293,6 +293,126 @@ property_list_text(pcmk__output_t *out, va_list args) { return pcmk_rc_ok; } +PCMK__OUTPUT_ARGS("resource-agent-action", "int", "const char *", "const char *", + "const char *", "const char *", "const char *", "GHashTable *", + "int", "int", "char *", "char *") +static int +resource_agent_action_default(pcmk__output_t *out, va_list args) { + int verbose = va_arg(args, int); + + const char *class = va_arg(args, const char *); + const char *provider = va_arg(args, const char *); + const char *type = va_arg(args, const char *); + const char *rsc_name = va_arg(args, const char *); + const char *action = va_arg(args, const char *); + GHashTable *overrides = va_arg(args, GHashTable *); + int rc = va_arg(args, int); + int status = va_arg(args, int); + char *stdout_data = va_arg(args, char *); + char *stderr_data = va_arg(args, char *); + + if (overrides) { + GHashTableIter iter; + char *name = NULL; + char *value = NULL; + + out->begin_list(out, NULL, NULL, "overrides"); + + g_hash_table_iter_init(&iter, overrides); + while (g_hash_table_iter_next(&iter, (gpointer *) &name, (gpointer *) &value)) { + out->message(out, "override", rsc_name, name, value); + } + + out->end_list(out); + } + + out->message(out, "agent-status", status, action, rsc_name, class, provider, + type, rc); + + /* hide output for validate-all if not in verbose */ + if (verbose == 0 && pcmk__str_eq(action, "validate-all", pcmk__str_casei)) { + return pcmk_rc_ok; + } + + if (stdout_data || stderr_data) { + xmlNodePtr doc = string2xml(stdout_data); + + if (doc != NULL) { + out->output_xml(out, "command", stdout_data); + xmlFreeNode(doc); + } else { + out->subprocess_output(out, rc, stdout_data, stderr_data); + } + } + + return pcmk_rc_ok; +} + +PCMK__OUTPUT_ARGS("resource-agent-action", "int", "const char *", "const char *", + "const char *", "const char *", "const char *", "GHashTable *", + "int", "int", "char *", "char *") +static int +resource_agent_action_xml(pcmk__output_t *out, va_list args) { + int verbose G_GNUC_UNUSED = va_arg(args, int); + + const char *class = va_arg(args, const char *); + const char *provider = va_arg(args, const char *); + const char *type = va_arg(args, const char *); + const char *rsc_name = va_arg(args, const char *); + const char *action = va_arg(args, const char *); + GHashTable *overrides = va_arg(args, GHashTable *); + int rc = va_arg(args, int); + int status = va_arg(args, int); + char *stdout_data = va_arg(args, char *); + char *stderr_data = va_arg(args, char *); + + xmlNodePtr node = pcmk__output_xml_create_parent(out, "resource-agent-action", + "action", action, + "class", class, + "type", type, + NULL); + + if (rsc_name) { + crm_xml_add(node, "rsc", rsc_name); + } + + if (provider) { + crm_xml_add(node, "provider", provider); + } + + if (overrides) { + GHashTableIter iter; + char *name = NULL; + char *value = NULL; + + out->begin_list(out, NULL, NULL, "overrides"); + + g_hash_table_iter_init(&iter, overrides); + while (g_hash_table_iter_next(&iter, (gpointer *) &name, (gpointer *) &value)) { + out->message(out, "override", rsc_name, name, value); + } + + out->end_list(out); + } + + out->message(out, "agent-status", status, action, rsc_name, class, provider, + type, rc); + + if (stdout_data || stderr_data) { + xmlNodePtr doc = string2xml(stdout_data); + + if (doc != NULL) { + out->output_xml(out, "command", stdout_data); + xmlFreeNode(doc); + } else { + out->subprocess_output(out, rc, stdout_data, stderr_data); + } + } + + pcmk__output_xml_pop_parent(out); + return pcmk_rc_ok; +} + PCMK__OUTPUT_ARGS("resource-check-list", "resource_checks_t *") static int resource_check_list_default(pcmk__output_t *out, va_list args) { @@ -658,6 +778,8 @@ static pcmk__message_entry_t fmt_functions[] = { { "override", "xml", override_xml }, { "property-list", "default", property_list_default }, { "property-list", "text", property_list_text }, + { "resource-agent-action", "default", resource_agent_action_default }, + { "resource-agent-action", "xml", resource_agent_action_xml }, { "resource-check-list", "default", resource_check_list_default }, { "resource-check-list", "xml", resource_check_list_xml }, { "resource-search-list", "default", resource_search_list_default }, -- 1.8.3.1 From b50b2418e1e997b42f5370b4672a3f105d74634f Mon Sep 17 00:00:00 2001 From: Chris Lumens Date: Fri, 4 Jun 2021 10:40:16 -0400 Subject: [PATCH 10/10] Feature: tools: Use the new resource-agent-action message. See: rhbz#1644628 --- tools/crm_resource_runtime.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/tools/crm_resource_runtime.c b/tools/crm_resource_runtime.c index ebf48bb..755be9f 100644 --- a/tools/crm_resource_runtime.c +++ b/tools/crm_resource_runtime.c @@ -1765,28 +1765,13 @@ cli_resource_execute_from_params(pcmk__output_t *out, const char *rsc_name, if (services_action_sync(op)) { exit_code = op->rc; - if (op->status == PCMK_LRM_OP_DONE) { - out->info(out, "Operation %s for %s (%s:%s:%s) returned: '%s' (%d)", - action, rsc_name, rsc_class, rsc_prov ? rsc_prov : "", rsc_type, - services_ocf_exitcode_str(op->rc), op->rc); - } else { - out->err(out, "Operation %s for %s (%s:%s:%s) failed: '%s' (%d)", - action, rsc_name, rsc_class, rsc_prov ? rsc_prov : "", rsc_type, - services_lrm_status_str(op->status), op->status); - } - - /* hide output for validate-all if not in verbose */ - if (resource_verbose == 0 && pcmk__str_eq(action, "validate-all", pcmk__str_casei)) - goto done; - - if (op->stdout_data || op->stderr_data) { - out->subprocess_output(out, op->rc, op->stdout_data, op->stderr_data); - } + out->message(out, "resource-agent-action", resource_verbose, rsc_class, + rsc_prov, rsc_type, rsc_name, action, override_hash, op->rc, + op->status, op->stdout_data, op->stderr_data); } else { exit_code = op->rc == 0 ? CRM_EX_ERROR : op->rc; } -done: services_action_free(op); /* See comment above about why we free params here. */ g_hash_table_destroy(params); -- 1.8.3.1