Blob Blame History Raw
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