From 7c35387a9896cb968cf4087b5cbed94af44e1ea5 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Fri, 14 May 2021 12:03:46 -0400
Subject: [PATCH 1/5] Feature: daemons: Convert pacemakerd to formatted output.
The main purpose of this is to finish getting pacemakerd moved off the
existing command line handling code (pcmk__cli_help in particular) so
that code can eventually be deprecated or removed. pacemakerd itself
does fairly little printing.
---
daemons/pacemakerd/pacemakerd.c | 58 ++++++++++++++++++++++++++++++-----------
1 file changed, 43 insertions(+), 15 deletions(-)
diff --git a/daemons/pacemakerd/pacemakerd.c b/daemons/pacemakerd/pacemakerd.c
index ce194bf..bd59729 100644
--- a/daemons/pacemakerd/pacemakerd.c
+++ b/daemons/pacemakerd/pacemakerd.c
@@ -25,6 +25,7 @@
#include <crm/common/ipc_internal.h>
#include <crm/common/mainloop.h>
#include <crm/common/cmdline_internal.h>
+#include <crm/common/output_internal.h>
#include <crm/cluster/internal.h>
#include <crm/cluster.h>
@@ -37,6 +38,14 @@ struct {
gboolean standby;
} options;
+static pcmk__output_t *out = NULL;
+
+static pcmk__supported_format_t formats[] = {
+ PCMK__SUPPORTED_FORMAT_NONE,
+ PCMK__SUPPORTED_FORMAT_TEXT,
+ { NULL, NULL, NULL }
+};
+
static gboolean
pid_cb(const gchar *option_name, const gchar *optarg, gpointer data, GError **err) {
return TRUE;
@@ -1167,10 +1176,10 @@ pacemakerd_event_cb(pcmk_ipc_api_t *pacemakerd_api,
}
static GOptionContext *
-build_arg_context(pcmk__common_args_t *args) {
+build_arg_context(pcmk__common_args_t *args, GOptionGroup **group) {
GOptionContext *context = NULL;
- context = pcmk__build_arg_context(args, NULL, NULL, NULL);
+ context = pcmk__build_arg_context(args, "text", group, NULL);
pcmk__add_main_args(context, entries);
return context;
}
@@ -1182,9 +1191,11 @@ main(int argc, char **argv)
GError *error = NULL;
+ int rc = pcmk_rc_ok;
+ GOptionGroup *output_group = NULL;
pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY);
gchar **processed_args = pcmk__cmdline_preproc(argv, "p");
- GOptionContext *context = build_arg_context(args);
+ GOptionContext *context = build_arg_context(args, &output_group);
bool old_instance_connected = false;
@@ -1195,23 +1205,30 @@ main(int argc, char **argv)
mainloop_add_signal(SIGHUP, pcmk_ignore);
mainloop_add_signal(SIGQUIT, pcmk_sigquit);
+ pcmk__register_formats(output_group, formats);
if (!g_option_context_parse_strv(context, &processed_args, &error)) {
exit_code = CRM_EX_USAGE;
goto done;
}
+ rc = pcmk__output_new(&out, args->output_ty, args->output_dest, argv);
+ if (rc != pcmk_rc_ok) {
+ exit_code = CRM_EX_ERROR;
+ g_set_error(&error, PCMK__EXITC_ERROR, exit_code, "Error creating output format %s: %s",
+ args->output_ty, pcmk_rc_str(rc));
+ goto done;
+ }
+
if (options.features) {
- printf("Pacemaker %s (Build: %s)\n Supporting v%s: %s\n", PACEMAKER_VERSION, BUILD_VERSION,
- CRM_FEATURE_SET, CRM_FEATURES);
+ out->info(out, "Pacemaker %s (Build: %s)\n Supporting v%s: %s", PACEMAKER_VERSION,
+ BUILD_VERSION, CRM_FEATURE_SET, CRM_FEATURES);
exit_code = CRM_EX_OK;
goto done;
}
if (args->version) {
- g_strfreev(processed_args);
- pcmk__free_arg_context(context);
- /* FIXME: When pacemakerd is converted to use formatted output, this can go. */
- pcmk__cli_help('v', CRM_EX_USAGE);
+ out->version(out, false);
+ goto done;
}
setenv("LC_ALL", "C", 1);
@@ -1248,6 +1265,13 @@ main(int argc, char **argv)
crm_ipc_close(old_instance);
crm_ipc_destroy(old_instance);
+ /* Don't allow any accidental output after this point. */
+ if (out != NULL) {
+ out->finish(out, exit_code, true, NULL);
+ pcmk__output_free(out);
+ out = NULL;
+ }
+
#ifdef SUPPORT_COROSYNC
if (mcp_read_config() == FALSE) {
exit_code = CRM_EX_UNAVAILABLE;
@@ -1333,6 +1357,11 @@ done:
g_strfreev(processed_args);
pcmk__free_arg_context(context);
- pcmk__output_and_clear_error(error, NULL);
+ pcmk__output_and_clear_error(error, out);
+
+ if (out != NULL) {
+ out->finish(out, exit_code, true, NULL);
+ pcmk__output_free(out);
+ }
crm_exit(exit_code);
}
--
1.8.3.1
From 35e6da64381fcb092d81ce16835cc28670b077cb Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Mon, 17 May 2021 10:04:04 -0400
Subject: [PATCH 2/5] Features: daemons: Output the pacemakerd feature list in
XML.
---
daemons/pacemakerd/pacemakerd.c | 45 ++++++++++++++++++++++++++++++++++++++---
1 file changed, 42 insertions(+), 3 deletions(-)
diff --git a/daemons/pacemakerd/pacemakerd.c b/daemons/pacemakerd/pacemakerd.c
index bd59729..93cf743 100644
--- a/daemons/pacemakerd/pacemakerd.c
+++ b/daemons/pacemakerd/pacemakerd.c
@@ -43,6 +43,42 @@ static pcmk__output_t *out = NULL;
static pcmk__supported_format_t formats[] = {
PCMK__SUPPORTED_FORMAT_NONE,
PCMK__SUPPORTED_FORMAT_TEXT,
+ PCMK__SUPPORTED_FORMAT_XML,
+ { NULL, NULL, NULL }
+};
+
+static int
+pacemakerd_features(pcmk__output_t *out, va_list args) {
+ out->info(out, "Pacemaker %s (Build: %s)\n Supporting v%s: %s", PACEMAKER_VERSION,
+ BUILD_VERSION, CRM_FEATURE_SET, CRM_FEATURES);
+ return pcmk_rc_ok;
+}
+
+static int
+pacemakerd_features_xml(pcmk__output_t *out, va_list args) {
+ gchar **feature_list = g_strsplit(CRM_FEATURES, " ", 0);
+
+ pcmk__output_xml_create_parent(out, "pacemakerd",
+ "version", PACEMAKER_VERSION,
+ "build", BUILD_VERSION,
+ "feature_set", CRM_FEATURE_SET,
+ NULL);
+ out->begin_list(out, NULL, NULL, "features");
+
+ for (char **s = feature_list; *s != NULL; s++) {
+ pcmk__output_create_xml_text_node(out, "feature", *s);
+ }
+
+ out->end_list(out);
+
+ g_strfreev(feature_list);
+ return pcmk_rc_ok;
+}
+
+static pcmk__message_entry_t fmt_functions[] = {
+ { "features", "default", pacemakerd_features },
+ { "features", "xml", pacemakerd_features_xml },
+
{ NULL, NULL, NULL }
};
@@ -200,7 +236,7 @@ static GOptionContext *
build_arg_context(pcmk__common_args_t *args, GOptionGroup **group) {
GOptionContext *context = NULL;
- context = pcmk__build_arg_context(args, "text", group, NULL);
+ context = pcmk__build_arg_context(args, "text (default), xml", group, NULL);
pcmk__add_main_args(context, entries);
return context;
}
@@ -241,9 +277,12 @@ main(int argc, char **argv)
goto done;
}
+ pcmk__force_args(context, &error, "%s --xml-simple-list", g_get_prgname());
+
+ pcmk__register_messages(out, fmt_functions);
+
if (options.features) {
- out->info(out, "Pacemaker %s (Build: %s)\n Supporting v%s: %s", PACEMAKER_VERSION,
- BUILD_VERSION, CRM_FEATURE_SET, CRM_FEATURES);
+ out->message(out, "features");
exit_code = CRM_EX_OK;
goto done;
}
--
1.8.3.1
From 5b7f5eb35b025b59805cf3c7c3dcb6a3cf4b71b3 Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Mon, 17 May 2021 11:09:53 -0400
Subject: [PATCH 3/5] Low: daemons: Conditionally enable logging in pacemakerd.
If we're doing an interactive command-line call, use
pcmk__cli_init_logging. At the moment, all command line calls except
for --shutdown do their work before logging would even come up, so we
really only need to do this for --shutdown.
If we're doing a daemon call, use crm_log_init.
---
daemons/pacemakerd/pacemakerd.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/daemons/pacemakerd/pacemakerd.c b/daemons/pacemakerd/pacemakerd.c
index 93cf743..c20bde7 100644
--- a/daemons/pacemakerd/pacemakerd.c
+++ b/daemons/pacemakerd/pacemakerd.c
@@ -296,8 +296,11 @@ main(int argc, char **argv)
pcmk__set_env_option("mcp", "true");
- pcmk__cli_init_logging("pacemakerd", args->verbosity);
- crm_log_init(NULL, LOG_INFO, TRUE, FALSE, argc, argv, FALSE);
+ if (options.shutdown) {
+ pcmk__cli_init_logging("pacemakerd", args->verbosity);
+ } else {
+ crm_log_init(NULL, LOG_INFO, TRUE, FALSE, argc, argv, FALSE);
+ }
crm_debug("Checking for existing Pacemaker instance");
old_instance = crm_ipc_new(CRM_SYSTEM_MCP, 0);
--
1.8.3.1
From 2393362bb7489e86d937ed46a1c5cfb93d9bf3ab Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Mon, 17 May 2021 11:58:06 -0400
Subject: [PATCH 4/5] Fix: include: Bump CRM_FEATURE_SET for new pacemakerd
args.
---
include/crm/crm.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/crm/crm.h b/include/crm/crm.h
index fdfc825..92a98fa 100644
--- a/include/crm/crm.h
+++ b/include/crm/crm.h
@@ -66,7 +66,7 @@ extern "C" {
* >=3.0.13: Fail counts include operation name and interval
* >=3.2.0: DC supports PCMK_LRM_OP_INVALID and PCMK_LRM_OP_NOT_CONNECTED
*/
-# define CRM_FEATURE_SET "3.10.0"
+# define CRM_FEATURE_SET "3.10.1"
/* Pacemaker's CPG protocols use fixed-width binary fields for the sender and
* recipient of a CPG message. This imposes an arbitrary limit on cluster node
--
1.8.3.1
From 3ad8edbd91631b87ef5f53fa2d68f0c8bbb9ee2b Mon Sep 17 00:00:00 2001
From: Chris Lumens <clumens@redhat.com>
Date: Mon, 17 May 2021 11:57:09 -0400
Subject: [PATCH 5/5] Feature: xml: Add schema for pacemakerd.
---
xml/Makefile.am | 1 +
xml/api/pacemakerd-2.10.rng | 28 ++++++++++++++++++++++++++++
2 files changed, 29 insertions(+)
create mode 100644 xml/api/pacemakerd-2.10.rng
diff --git a/xml/Makefile.am b/xml/Makefile.am
index 12a51c5..b9448d4 100644
--- a/xml/Makefile.am
+++ b/xml/Makefile.am
@@ -56,6 +56,7 @@ API_request_base = command-output \
crm_simulate \
crmadmin \
digests \
+ pacemakerd \
stonith_admin \
version
diff --git a/xml/api/pacemakerd-2.10.rng b/xml/api/pacemakerd-2.10.rng
new file mode 100644
index 0000000..41a11e7
--- /dev/null
+++ b/xml/api/pacemakerd-2.10.rng
@@ -0,0 +1,28 @@
+<?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-pacemakerd"/>
+ </start>
+
+ <define name="element-pacemakerd">
+ <element name="pacemakerd">
+ <attribute name="version"> <text /> </attribute>
+ <attribute name="build"> <text /> </attribute>
+ <attribute name="feature_set"> <text /> </attribute>
+
+ <optional>
+ <ref name="feature-list" />
+ </optional>
+ </element>
+ </define>
+
+ <define name="feature-list">
+ <element name="features">
+ <oneOrMore>
+ <element name="feature"> <text/> </element>
+ </oneOrMore>
+ </element>
+ </define>
+</grammar>
--
1.8.3.1