Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/include/crm/common/output_internal.h b/include/crm/common/output_internal.h
index 8fd5ed4a20..a01cfb8eb1 100644
--- a/include/crm/common/output_internal.h
+++ b/include/crm/common/output_internal.h
@@ -1,937 +1,937 @@
/*
* Copyright 2019-2022 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 PCMK__OUTPUT_INTERNAL__H
# define PCMK__OUTPUT_INTERNAL__H
# include <stdbool.h>
# include <stdio.h>
# include <libxml/tree.h>
# include <libxml/HTMLtree.h>
# include <glib.h>
# include <crm/common/results.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \file
* \brief Formatted output for pacemaker tools
*/
-# define PCMK__API_VERSION "2.28"
+# define PCMK__API_VERSION "2.29"
#if defined(PCMK__WITH_ATTRIBUTE_OUTPUT_ARGS)
# define PCMK__OUTPUT_ARGS(ARGS...) __attribute__((output_args(ARGS)))
#else
# define PCMK__OUTPUT_ARGS(ARGS...)
#endif
typedef struct pcmk__output_s pcmk__output_t;
/*!
* \internal
* \brief The type of a function that creates a ::pcmk__output_t.
*
* Instances of this type are passed to pcmk__register_format(), stored in an
* internal data structure, and later accessed by pcmk__output_new(). For
* examples, see pcmk__mk_xml_output() and pcmk__mk_text_output().
*
* \param[in] argv The list of command line arguments.
*/
typedef pcmk__output_t * (*pcmk__output_factory_t)(char **argv);
/*!
* \internal
* \brief The type of a custom message formatting function.
*
* These functions are defined by various libraries to support formatting of
* types aside from the basic types provided by a ::pcmk__output_t.
*
* The meaning of the return value will be different for each message.
* In general, however, 0 should be returned on success and a positive value
* on error.
*
* \param[in,out] out Output object to use to display message
* \param[in,out] args Message-specific arguments needed
*
* \note These functions must not call va_start or va_end - that is done
* automatically before the custom formatting function is called.
*/
typedef int (*pcmk__message_fn_t)(pcmk__output_t *out, va_list args);
/*!
* \internal
* \brief Internal type for tracking custom messages.
*
* Each library can register functions that format custom message types. These
* are commonly used to handle some library-specific type. Registration is
* done by first defining a table of ::pcmk__message_entry_t structures and
* then passing that table to pcmk__register_messages(). Separate handlers
* can be defined for the same message, but for different formats (xml vs.
* text). Unknown formats will be ignored.
*
* Additionally, a "default" value for fmt_table can be used. In this case,
* fn will be registered for all supported formats. It is also possible to
* register a default and then override that registration with a format-specific
* function if necessary.
*
* \note The ::pcmk__message_entry_t table is processed in one pass, in order,
* from top to bottom. This means later entries with the same message_id will
* override previous ones. Thus, any default entry must come before any
* format-specific entries for the same message_id.
*/
typedef struct pcmk__message_entry_s {
/*!
* \brief The message to be handled.
*
* This must be the same ID that is passed to the message function of
* a ::pcmk__output_t. Unknown message IDs will be ignored.
*/
const char *message_id;
/*!
* \brief The format type this handler is for.
*
* This name must match the fmt_name of the currently active formatter in
* order for the registered function to be called. It is valid to have
* multiple entries for the same message_id but with different fmt_name
* values.
*/
const char *fmt_name;
/*!
* \brief The function to be called for message_id given a match on
* fmt_name. See comments on ::pcmk__message_fn_t.
*/
pcmk__message_fn_t fn;
} pcmk__message_entry_t;
/*!
* \internal
* \brief This structure contains everything needed to add support for a
* single output formatter to a command line program.
*/
typedef struct pcmk__supported_format_s {
/*!
* \brief The name of this output formatter, which should match the
* fmt_name parameter in some ::pcmk__output_t structure.
*/
const char *name;
/*!
* \brief A function that creates a ::pcmk__output_t.
*/
pcmk__output_factory_t create;
/*!
* \brief Format-specific command line options. This can be NULL if
* no command line options should be supported.
*/
GOptionEntry *options;
} pcmk__supported_format_t;
/* The following three blocks need to be updated each time a new base formatter
* is added.
*/
extern GOptionEntry pcmk__html_output_entries[];
extern GOptionEntry pcmk__log_output_entries[];
extern GOptionEntry pcmk__none_output_entries[];
extern GOptionEntry pcmk__text_output_entries[];
extern GOptionEntry pcmk__xml_output_entries[];
pcmk__output_t *pcmk__mk_html_output(char **argv);
pcmk__output_t *pcmk__mk_log_output(char **argv);
pcmk__output_t *pcmk__mk_none_output(char **argv);
pcmk__output_t *pcmk__mk_text_output(char **argv);
pcmk__output_t *pcmk__mk_xml_output(char **argv);
#define PCMK__SUPPORTED_FORMAT_HTML { "html", pcmk__mk_html_output, pcmk__html_output_entries }
#define PCMK__SUPPORTED_FORMAT_LOG { "log", pcmk__mk_log_output, pcmk__log_output_entries }
#define PCMK__SUPPORTED_FORMAT_NONE { PCMK__VALUE_NONE, pcmk__mk_none_output, \
pcmk__none_output_entries }
#define PCMK__SUPPORTED_FORMAT_TEXT { "text", pcmk__mk_text_output, pcmk__text_output_entries }
#define PCMK__SUPPORTED_FORMAT_XML { "xml", pcmk__mk_xml_output, pcmk__xml_output_entries }
/*!
* \brief This structure contains everything that makes up a single output
* formatter.
*
* Instances of this structure may be created by calling pcmk__output_new()
* with the name of the desired formatter. They should later be freed with
* pcmk__output_free().
*/
struct pcmk__output_s {
/*!
* \brief The name of this output formatter.
*/
const char *fmt_name;
/*!
* \brief Should this formatter supress most output?
*
* \note This setting is not respected by all formatters. In general,
* machine-readable output formats will not support this while
* user-oriented formats will. Callers should use is_quiet()
* to test whether to print or not.
*/
bool quiet;
/*!
* \brief A copy of the request that generated this output.
*
* In the case of command line usage, this would be the command line
* arguments. For other use cases, it could be different.
*/
gchar *request;
/*!
* \brief Where output should be written.
*
* This could be a file handle, or stdout or stderr. This is really only
* useful internally.
*/
FILE *dest;
/*!
* \brief Custom messages that are currently registered on this formatter.
*
* Keys are the string message IDs, values are ::pcmk__message_fn_t function
* pointers.
*/
GHashTable *messages;
/*!
* \brief Implementation-specific private data.
*
* Each individual formatter may have some private data useful in its
* implementation. This points to that data. Callers should not rely on
* its contents or structure.
*/
void *priv;
/*!
* \internal
* \brief Take whatever actions are necessary to prepare out for use. This is
* called by pcmk__output_new(). End users should not need to call this.
*
* \note For formatted output implementers - This function should be written in
* such a way that it can be called repeatedly on an already initialized
* object without causing problems, or on a previously finished object
* without crashing.
*
* \param[in,out] out The output functions structure.
*
* \return true on success, false on error.
*/
bool (*init) (pcmk__output_t *out);
/*!
* \internal
* \brief Free the private formatter-specific data.
*
* This is called from pcmk__output_free() and does not typically need to be
* called directly.
*
* \param[in,out] out The output functions structure.
*/
void (*free_priv) (pcmk__output_t *out);
/*!
* \internal
* \brief Take whatever actions are necessary to end formatted output.
*
* This could include flushing output to a file, but does not include freeing
* anything. The finish method can potentially be fairly complicated, adding
* additional information to the internal data structures or doing whatever
* else. It is therefore suggested that finish only be called once.
*
* \note The print parameter will only affect those formatters that do all
* their output at the end. Console-oriented formatters typically print
* a line at a time as they go, so this parameter will not affect them.
* Structured formatters will honor it, however.
*
* \note The copy_dest parameter does not apply to all formatters. Console-
* oriented formatters do not build up a structure as they go, and thus
* do not have anything to return. Structured formatters will honor it,
* however. Note that each type of formatter will return a different
* type of value in this parameter. To use this parameter, call this
* function like so:
*
* \code
* xmlNode *dest = NULL;
* out->finish(out, exit_code, false, (void **) &dest);
* \endcode
*
* \param[in,out] out The output functions structure.
* \param[in] exit_status The exit value of the whole program.
* \param[in] print Whether this function should write any output.
* \param[out] copy_dest A destination to store a copy of the internal
* data structure for this output, or NULL if no
* copy is required. The caller should free this
* memory when done with it.
*/
void (*finish) (pcmk__output_t *out, crm_exit_t exit_status, bool print,
void **copy_dest);
/*!
* \internal
* \brief Finalize output and then immediately set back up to start a new set
* of output.
*
* This is conceptually the same as calling finish and then init, though in
* practice more be happening behind the scenes.
*
* \note This function differs from finish in that no exit_status is added.
* The idea is that the program is not shutting down, so there is not
* yet a final exit code. Call finish on the last time through if this
* is needed.
*
* \param[in,out] out The output functions structure.
*/
void (*reset) (pcmk__output_t *out);
/*!
* \internal
* \brief Register a custom message.
*
* \param[in,out] out The output functions structure.
* \param[in] message_id The name of the message to register. This name
* will be used as the message_id parameter to the
* message function in order to call the custom
* format function.
* \param[in] fn The custom format function to call for message_id.
*/
void (*register_message) (pcmk__output_t *out, const char *message_id,
pcmk__message_fn_t fn);
/*!
* \internal
* \brief Call a previously registered custom message.
*
* \param[in,out] out The output functions structure.
* \param[in] message_id The name of the message to call. This name must
* be the same as the message_id parameter of some
* previous call to register_message.
* \param[in] ... Arguments to be passed to the registered function.
*
* \return A standard Pacemaker return code. Generally: 0 if a function was
* registered for the message, that function was called, and returned
* successfully; EINVAL if no function was registered; or pcmk_rc_no_output
* if a function was called but produced no output.
*/
int (*message) (pcmk__output_t *out, const char *message_id, ...);
/*!
* \internal
* \brief Format the output of a completed subprocess.
*
* \param[in,out] out The output functions structure.
* \param[in] exit_status The exit value of the subprocess.
* \param[in] proc_stdout stdout from the completed subprocess.
* \param[in] proc_stderr stderr from the completed subprocess.
*/
void (*subprocess_output) (pcmk__output_t *out, int exit_status,
const char *proc_stdout, const char *proc_stderr);
/*!
* \internal
* \brief Format version information. This is useful for the --version
* argument of command line tools.
*
* \param[in,out] out The output functions structure.
* \param[in] extended Add additional version information.
*/
void (*version) (pcmk__output_t *out, bool extended);
/*!
* \internal
* \brief Format an informational message that should be shown to
* to an interactive user. Not all formatters will do this.
*
* \note A newline will automatically be added to the end of the format
* string, so callers should not include a newline.
*
* \note It is possible for a formatter that supports this method to
* still not print anything out if is_quiet returns true.
*
* \param[in,out] out The output functions structure.
* \param[in] buf The message to be printed.
* \param[in] ... Arguments to be formatted.
*
* \return A standard Pacemaker return code. Generally: pcmk_rc_ok
* if output was produced and pcmk_rc_no_output if it was not.
* As not all formatters implement this function, those that
* do not will always just return pcmk_rc_no_output.
*/
int (*info) (pcmk__output_t *out, const char *format, ...) G_GNUC_PRINTF(2, 3);
/*!
* \internal
* \brief Like \p info() but for messages that should appear only
* transiently. Not all formatters will do this.
*
* The originally envisioned use case is for console output, where a
* transient status-related message may be quickly overwritten by a refresh.
*
* \param[in,out] out The output functions structure.
* \param[in] format The format string of the message to be printed.
* \param[in] ... Arguments to be formatted.
*
* \return A standard Pacemaker return code. Generally: \p pcmk_rc_ok if
* output was produced and \p pcmk_rc_no_output if it was not. As
* not all formatters implement this function, those that do not
* will always just return \p pcmk_rc_no_output.
*/
int (*transient) (pcmk__output_t *out, const char *format, ...)
G_GNUC_PRINTF(2, 3);
/*!
* \internal
* \brief Format an error message that should be shown to an interactive
* user. Not all formatters will do this.
*
* \note A newline will automatically be added to the end of the format
* string, so callers should not include a newline.
*
* \note Formatters that support this method should always generate output,
* even if is_quiet returns true.
*
* \param[in,out] out The output functions structure.
* \param[in] buf The message to be printed.
* \param[in] ... Arguments to be formatted.
*/
void (*err) (pcmk__output_t *out, const char *format, ...) G_GNUC_PRINTF(2, 3);
/*!
* \internal
* \brief Format already formatted XML.
*
* \param[in,out] out The output functions structure.
* \param[in] name A name to associate with the XML.
* \param[in] buf The XML in a string.
*/
void (*output_xml) (pcmk__output_t *out, const char *name, const char *buf);
/*!
* \internal
* \brief Start a new list of items.
*
* \note For text output, this corresponds to another level of indentation. For
* XML output, this corresponds to wrapping any following output in another
* layer of tags.
*
* \note If singular_noun and plural_noun are non-NULL, calling end_list will
* result in a summary being added.
*
* \param[in,out] out The output functions structure.
* \param[in] singular_noun When outputting the summary for a list with
* one item, the noun to use.
* \param[in] plural_noun When outputting the summary for a list with
* more than one item, the noun to use.
* \param[in] format The format string.
* \param[in] ... Arguments to be formatted.
*/
void (*begin_list) (pcmk__output_t *out, const char *singular_noun,
const char *plural_noun, const char *format, ...)
G_GNUC_PRINTF(4, 5);
/*!
* \internal
* \brief Format a single item in a list.
*
* \param[in,out] out The output functions structure.
* \param[in] name A name to associate with this item.
* \param[in] format The format string.
* \param[in] ... Arguments to be formatted.
*/
void (*list_item) (pcmk__output_t *out, const char *name, const char *format, ...)
G_GNUC_PRINTF(3, 4);
/*!
* \internal
* \brief Increment the internal counter of the current list's length.
*
* Typically, this counter is maintained behind the scenes as a side effect
* of calling list_item(). However, custom functions that maintain lists
* some other way will need to manage this counter manually. This is
* useful for implementing custom message functions and should not be
* needed otherwise.
*
* \param[in,out] out The output functions structure.
*/
void (*increment_list) (pcmk__output_t *out);
/*!
* \internal
* \brief Conclude a list.
*
* \note If begin_list was called with non-NULL for both the singular_noun
* and plural_noun arguments, this function will output a summary.
* Otherwise, no summary will be added.
*
* \param[in,out] out The output functions structure.
*/
void (*end_list) (pcmk__output_t *out);
/*!
* \internal
* \brief Should anything be printed to the user?
*
* \note This takes into account both the \p quiet value as well as the
* current formatter.
*
* \param[in,out] out The output functions structure.
*
* \return true if output should be supressed, false otherwise.
*/
bool (*is_quiet) (pcmk__output_t *out);
/*!
* \internal
* \brief Output a spacer. Not all formatters will do this.
*
* \param[in,out] out The output functions structure.
*/
void (*spacer) (pcmk__output_t *out);
/*!
* \internal
* \brief Output a progress indicator. This is likely only useful for
* plain text, console based formatters.
*
* \param[in,out] out The output functions structure
* \param[in] end If true, output a newline afterwards (this should
* only be used the last time this function is called)
*
*/
void (*progress) (pcmk__output_t *out, bool end);
/*!
* \internal
* \brief Prompt the user for input. Not all formatters will do this.
*
* \note This function is part of pcmk__output_t, but unlike all other
* function it does not take that as an argument. In general, a
* prompt will go directly to the screen and therefore bypass any
* need to use the formatted output code to decide where and how
* to display.
*
* \param[in] prompt The prompt to display. This is required.
* \param[in] echo If true, echo the user's input to the screen. Set
* to false for password entry.
* \param[out] dest Where to store the user's response. This is
* required.
*/
void (*prompt) (const char *prompt, bool echo, char **dest);
};
/*!
* \internal
* \brief Call a formatting function for a previously registered message.
*
* \note This function is for implementing custom formatters. It should not
* be called directly. Instead, call out->message.
*
* \param[in,out] out The output functions structure.
* \param[in] message_id The message to be handled. Unknown messages
* will be ignored.
* \param[in] ... Arguments to be passed to the registered function.
*/
int
pcmk__call_message(pcmk__output_t *out, const char *message_id, ...);
/*!
* \internal
* \brief Free a ::pcmk__output_t structure that was previously created by
* pcmk__output_new().
*
* \note While the create and finish functions are designed in such a way that
* they can be called repeatedly, this function will completely free the
* memory of the object. Once this function has been called, producing
* more output requires starting over from pcmk__output_new().
*
* \param[in,out] out The output structure.
*/
void pcmk__output_free(pcmk__output_t *out);
/*!
* \internal
* \brief Create a new ::pcmk__output_t structure.
*
* \param[in,out] out The destination of the new ::pcmk__output_t.
* \param[in] fmt_name How should output be formatted?
* \param[in] filename Where should formatted output be written to? This
* can be a filename (which will be overwritten if it
* already exists), or NULL or "-" for stdout. For no
* output, pass a filename of "/dev/null".
* \param[in] argv The list of command line arguments.
*
* \return Standard Pacemaker return code
*/
int pcmk__output_new(pcmk__output_t **out, const char *fmt_name,
const char *filename, char **argv);
/*!
* \internal
* \brief Register a new output formatter, making it available for use
* the same as a base formatter.
*
* \param[in,out] group A ::GOptionGroup that formatted output related command
* line arguments should be added to. This can be NULL
* for use outside of command line programs.
* \param[in] name The name of the format. This will be used to select a
* format from command line options and for displaying help.
* \param[in] create A function that creates a ::pcmk__output_t.
* \param[in] options Format-specific command line options. These will be
* added to the context. This argument can also be NULL.
*
* \return Standard Pacemaker return code
*/
int
pcmk__register_format(GOptionGroup *group, const char *name,
pcmk__output_factory_t create,
const GOptionEntry *options);
/*!
* \internal
* \brief Register an entire table of output formatters at once.
*
* \param[in,out] group A ::GOptionGroup that formatted output related command
* line arguments should be added to. This can be NULL
* for use outside of command line programs.
* \param[in] table An array of ::pcmk__supported_format_t which should
* all be registered. This array must be NULL-terminated.
*
*/
void
pcmk__register_formats(GOptionGroup *group,
const pcmk__supported_format_t *table);
/*!
* \internal
* \brief Unregister a previously registered table of custom formatting
* functions and destroy the internal data structures associated with them.
*/
void
pcmk__unregister_formats(void);
/*!
* \internal
* \brief Register a function to handle a custom message.
*
* \note This function is for implementing custom formatters. It should not
* be called directly. Instead, call out->register_message.
*
* \param[in,out] out The output functions structure.
* \param[in] message_id The message to be handled.
* \param[in] fn The custom format function to call for message_id.
*/
void
pcmk__register_message(pcmk__output_t *out, const char *message_id,
pcmk__message_fn_t fn);
/*!
* \internal
* \brief Register an entire table of custom formatting functions at once.
*
* This table can contain multiple formatting functions for the same message ID
* if they are for different format types.
*
* \param[in,out] out The output functions structure.
* \param[in] table An array of ::pcmk__message_entry_t values which should
* all be registered. This array must be NULL-terminated.
*/
void
pcmk__register_messages(pcmk__output_t *out,
const pcmk__message_entry_t *table);
/* Functions that are useful for implementing custom message formatters */
/*!
* \internal
* \brief A printf-like function.
*
* This function writes to out->dest and indents the text to the current level
* of the text formatter's nesting. This function should be used when implementing
* custom message functions for the text output format. It should not be used
* for any other purpose.
*
* Typically, this function should be used instead of printf.
*
* \param[in,out] out The output functions structure.
* \param[in] format The format string.
* \param[in] ... Arguments to be passed to the format string.
*/
void
pcmk__indented_printf(pcmk__output_t *out, const char *format, ...) G_GNUC_PRINTF(2, 3);
/*!
* \internal
* \brief A vprintf-like function.
*
* This function is like pcmk__indented_printf(), except it takes a va_list instead
* of a list of arguments. This function should be used when implementing custom
* functions for the text output format. It should not be used for any other purpose.
*
* Typically, this function should be used instead of vprintf.
*
* \param[in,out] out The output functions structure.
* \param[in] format The format string.
* \param[in] args A list of arguments to apply to the format string.
*/
void
pcmk__indented_vprintf(pcmk__output_t *out, const char *format, va_list args) G_GNUC_PRINTF(2, 0);
/*!
* \internal
* \brief A printf-like function.
*
* This function writes to out->dest without indenting the text. This function
* should be used when implementing custom message functions for the text output
* format. It should not be used for any other purpose.
*
* \param[in,out] out The output functions structure.
* \param[in] format The format string.
* \param[in] ... Arguments to be passed to the format string.
*/
void
pcmk__formatted_printf(pcmk__output_t *out, const char *format, ...) G_GNUC_PRINTF(2, 3);
/*!
* \internal
* \brief A vprintf-like function.
*
* This function is like pcmk__formatted_printf(), except it takes a va_list instead
* of a list of arguments. This function should be used when implementing custom
* message functions for the text output format. It should not be used for any
* other purpose.
*
* \param[in,out] out The output functions structure.
* \param[in] format The format string.
* \param[in] args A list of arguments to apply to the format string.
*/
void
pcmk__formatted_vprintf(pcmk__output_t *out, const char *format, va_list args) G_GNUC_PRINTF(2, 0);
/*!
* \internal
* \brief Prompt the user for input.
*
* \param[in] prompt The prompt to display
* \param[in] echo If true, echo the user's input to the screen. Set
* to false for password entry.
* \param[out] dest Where to store the user's response.
*/
void
pcmk__text_prompt(const char *prompt, bool echo, char **dest);
/*!
* \internal
* \brief Set the log level used by the formatted output logger.
*
* \param[in,out] out The output functions structure.
* \param[in] log_level The log level constant (LOG_INFO, LOG_ERR, etc.)
* to use.
*
* \note By default, LOG_INFO is used.
* \note Almost all formatted output messages will respect this setting.
* However, out->err will always log at LOG_ERR.
*/
void
pcmk__output_set_log_level(pcmk__output_t *out, int log_level);
/*!
* \internal
* \brief Create and return a new XML node with the given name, as a child of the
* current list parent. The new node is then added as the new list parent,
* meaning all subsequent nodes will be its children. This is used when
* implementing custom functions.
*
* \param[in,out] out The output functions structure.
* \param[in] name The name of the node to be created.
* \param[in] ... Name/value pairs to set as XML properties.
*/
xmlNodePtr
pcmk__output_xml_create_parent(pcmk__output_t *out, const char *name, ...)
G_GNUC_NULL_TERMINATED;
/*!
* \internal
* \brief Add a copy of the given node as a child of the current list parent.
* This is used when implementing custom message functions.
*
* \param[in,out] out The output functions structure.
* \param[in] node An XML node to copy as a child.
*/
void
pcmk__output_xml_add_node_copy(pcmk__output_t *out, xmlNodePtr node);
/*!
* \internal
* \brief Create and return a new XML node with the given name, as a child of the
* current list parent. This is used when implementing custom functions.
*
* \param[in,out] out The output functions structure.
* \param[in] name The name of the node to be created.
* \param[in] ... Name/value pairs to set as XML properties.
*/
xmlNodePtr
pcmk__output_create_xml_node(pcmk__output_t *out, const char *name, ...)
G_GNUC_NULL_TERMINATED;
/*!
* \internal
* \brief Like pcmk__output_create_xml_node(), but add the given text content to the
* new node.
*
* \param[in,out] out The output functions structure.
* \param[in] name The name of the node to be created.
* \param[in] content The text content of the node.
*/
xmlNodePtr
pcmk__output_create_xml_text_node(pcmk__output_t *out, const char *name, const char *content);
/*!
* \internal
* \brief Push a parent XML node onto the stack. This is used when implementing
* custom message functions.
*
* The XML output formatter maintains an internal stack to keep track of which nodes
* are parents in order to build up the tree structure. This function can be used
* to temporarily push a new node onto the stack. After calling this function, any
* other formatting functions will have their nodes added as children of this new
* parent.
*
* \param[in,out] out The output functions structure
* \param[in] parent XML node to add
*/
void
pcmk__output_xml_push_parent(pcmk__output_t *out, xmlNodePtr parent);
/*!
* \internal
* \brief Pop a parent XML node onto the stack. This is used when implementing
* custom message functions.
*
* This function removes a parent node from the stack. See pcmk__xml_push_parent()
* for more details.
*
* \note Little checking is done with this function. Be sure you only pop parents
* that were previously pushed. In general, it is best to keep the code between
* push and pop simple.
*
* \param[in,out] out The output functions structure.
*/
void
pcmk__output_xml_pop_parent(pcmk__output_t *out);
/*!
* \internal
* \brief Peek a parent XML node onto the stack. This is used when implementing
* custom message functions.
*
* This function peeks a parent node on stack. See pcmk__xml_push_parent()
* for more details. It has no side-effect and can be called for an empty stack.
*
* \note Little checking is done with this function.
*
* \param[in,out] out The output functions structure.
*
* \return NULL if stack is empty, otherwise the parent of the stack.
*/
xmlNodePtr
pcmk__output_xml_peek_parent(pcmk__output_t *out);
/*!
* \internal
* \brief Create a new XML node consisting of the provided text inside an HTML
* element node of the given name.
*
* \param[in,out] out The output functions structure.
* \param[in] element_name The name of the new HTML element.
* \param[in] id The CSS ID selector to apply to this element.
* If NULL, no ID is added.
* \param[in] class_name The CSS class selector to apply to this element.
* If NULL, no class is added.
* \param[in] text The text content of the node.
*/
xmlNodePtr
pcmk__output_create_html_node(pcmk__output_t *out, const char *element_name, const char *id,
const char *class_name, const char *text);
/*!
* \internal
* \brief Add an HTML tag to the <head> section.
*
* The arguments after name are a NULL-terminated list of keys and values,
* all of which will be added as attributes to the given tag. For instance,
* the following code would generate the tag "<meta http-equiv='refresh' content='19'>":
*
* \code
* pcmk__html_add_header("meta", "http-equiv", "refresh", "content", "19", NULL);
* \endcode
*
* \param[in] name The HTML tag for the new node.
* \param[in] ... A NULL-terminated key/value list of attributes.
*/
void
pcmk__html_add_header(const char *name, ...)
G_GNUC_NULL_TERMINATED;
/*!
* \internal
* \brief Handle end-of-program error reporting
*
* \param[in,out] error A GError object potentially containing some error.
* If NULL, do nothing.
* \param[in,out] out The output functions structure. If NULL, any errors
* will simply be printed to stderr.
*/
void pcmk__output_and_clear_error(GError *error, pcmk__output_t *out);
int pcmk__xml_output_new(pcmk__output_t **out, xmlNodePtr *xml);
void pcmk__xml_output_finish(pcmk__output_t *out, xmlNodePtr *xml);
int pcmk__log_output_new(pcmk__output_t **out);
int pcmk__text_output_new(pcmk__output_t **out, const char *filename);
#if defined(PCMK__UNIT_TESTING)
/* If we are building libcrmcommon_test.a, add this accessor function so we can
* inspect the internal formatters hash table.
*/
GHashTable *pcmk__output_formatters(void);
#endif
#define PCMK__OUTPUT_SPACER_IF(out_obj, cond) \
if (cond) { \
out->spacer(out); \
}
#define PCMK__OUTPUT_LIST_HEADER(out_obj, cond, retcode, title...) \
if (retcode == pcmk_rc_no_output) { \
PCMK__OUTPUT_SPACER_IF(out_obj, cond); \
retcode = pcmk_rc_ok; \
out_obj->begin_list(out_obj, NULL, NULL, title); \
}
#define PCMK__OUTPUT_LIST_FOOTER(out_obj, retcode) \
if (retcode == pcmk_rc_ok) { \
out_obj->end_list(out_obj); \
}
#ifdef __cplusplus
}
#endif
#endif
diff --git a/xml/api/crm_mon-2.29.rng b/xml/api/crm_mon-2.29.rng
index 45a60592b3..9cc554cf75 100644
--- a/xml/api/crm_mon-2.29.rng
+++ b/xml/api/crm_mon-2.29.rng
@@ -1,213 +1,213 @@
<?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-crm-mon"/>
</start>
<define name="element-crm-mon">
<choice>
<ref name="element-crm-mon-disconnected" />
<group>
<optional>
<externalRef href="pacemakerd-health-2.25.rng" />
</optional>
<optional>
<ref name="element-summary" />
</optional>
<optional>
<ref name="nodes-list" />
</optional>
<optional>
<ref name="resources-list" />
</optional>
<optional>
<ref name="node-attributes-list" />
</optional>
<optional>
<externalRef href="node-history-2.12.rng"/>
</optional>
<optional>
<ref name="failures-list" />
</optional>
<optional>
<ref name="fence-event-list" />
</optional>
<optional>
<ref name="tickets-list" />
</optional>
<optional>
<ref name="bans-list" />
</optional>
</group>
</choice>
</define>
<define name="element-crm-mon-disconnected">
<element name="crm-mon-disconnected">
<optional>
<attribute name="description"> <text /> </attribute>
</optional>
<optional>
<attribute name="pacemakerd-state"> <text /> </attribute>
</optional>
</element>
</define>
<define name="element-summary">
<element name="summary">
<optional>
<element name="stack">
<attribute name="type"> <text /> </attribute>
<optional>
<attribute name="pacemakerd-state">
<text />
</attribute>
</optional>
</element>
</optional>
<optional>
<element name="current_dc">
<attribute name="present"> <data type="boolean" /> </attribute>
<optional>
<group>
<attribute name="version"> <text /> </attribute>
<attribute name="name"> <text /> </attribute>
<attribute name="id"> <text /> </attribute>
<attribute name="with_quorum"> <data type="boolean" /> </attribute>
</group>
</optional>
<optional>
<attribute name="mixed_version"> <data type="boolean" /> </attribute>
</optional>
</element>
</optional>
<optional>
<element name="last_update">
<attribute name="time"> <text /> </attribute>
<optional>
<attribute name="origin"> <text /> </attribute>
</optional>
</element>
<element name="last_change">
<attribute name="time"> <text /> </attribute>
<attribute name="user"> <text /> </attribute>
<attribute name="client"> <text /> </attribute>
<attribute name="origin"> <text /> </attribute>
</element>
</optional>
<optional>
<element name="nodes_configured">
<attribute name="number"> <data type="nonNegativeInteger" /> </attribute>
</element>
<element name="resources_configured">
<attribute name="number"> <data type="nonNegativeInteger" /> </attribute>
<attribute name="disabled"> <data type="nonNegativeInteger" /> </attribute>
<attribute name="blocked"> <data type="nonNegativeInteger" /> </attribute>
</element>
</optional>
<optional>
<element name="cluster_options">
<attribute name="stonith-enabled"> <data type="boolean" /> </attribute>
<attribute name="symmetric-cluster"> <data type="boolean" /> </attribute>
<attribute name="no-quorum-policy"> <text /> </attribute>
<attribute name="maintenance-mode"> <data type="boolean" /> </attribute>
<attribute name="stop-all-resources"> <data type="boolean" /> </attribute>
<attribute name="stonith-timeout-ms"> <data type="integer" /> </attribute>
<attribute name="priority-fencing-delay-ms"> <data type="integer" /> </attribute>
</element>
</optional>
</element>
</define>
<define name="resources-list">
<element name="resources">
<zeroOrMore>
- <externalRef href="resources-2.28.rng" />
+ <externalRef href="resources-2.29.rng" />
</zeroOrMore>
</element>
</define>
<define name="nodes-list">
<element name="nodes">
<zeroOrMore>
- <externalRef href="nodes-2.28.rng" />
+ <externalRef href="nodes-2.29.rng" />
</zeroOrMore>
</element>
</define>
<define name="node-attributes-list">
<element name="node_attributes">
<zeroOrMore>
<externalRef href="node-attrs-2.8.rng" />
</zeroOrMore>
</element>
</define>
<define name="failures-list">
<element name="failures">
<zeroOrMore>
<externalRef href="failure-2.8.rng" />
</zeroOrMore>
</element>
</define>
<define name="fence-event-list">
<element name="fence_history">
<optional>
<attribute name="status"> <data type="integer" /> </attribute>
</optional>
<zeroOrMore>
<externalRef href="fence-event-2.15.rng" />
</zeroOrMore>
</element>
</define>
<define name="tickets-list">
<element name="tickets">
<zeroOrMore>
<ref name="element-ticket" />
</zeroOrMore>
</element>
</define>
<define name="bans-list">
<element name="bans">
<zeroOrMore>
<ref name="element-ban" />
</zeroOrMore>
</element>
</define>
<define name="element-ticket">
<element name="ticket">
<attribute name="id"> <text /> </attribute>
<attribute name="status">
<choice>
<value>granted</value>
<value>revoked</value>
</choice>
</attribute>
<attribute name="standby"> <data type="boolean" /> </attribute>
<optional>
<attribute name="last-granted"> <text /> </attribute>
</optional>
</element>
</define>
<define name="element-ban">
<element name="ban">
<attribute name="id"> <text /> </attribute>
<attribute name="resource"> <text /> </attribute>
<attribute name="node"> <text /> </attribute>
<attribute name="weight"> <data type="integer" /> </attribute>
<attribute name="promoted-only"> <data type="boolean" /> </attribute>
<!-- DEPRECATED: master_only is a duplicate of promoted-only that is
provided solely for API backward compatibility. It will be
removed in a future release. Check promoted-only instead.
-->
<attribute name="master_only"> <data type="boolean" /> </attribute>
</element>
</define>
</grammar>
diff --git a/xml/api/crm_resource-2.29.rng b/xml/api/crm_resource-2.29.rng
index 901b81d74d..d95fd56a87 100644
--- a/xml/api/crm_resource-2.29.rng
+++ b/xml/api/crm_resource-2.29.rng
@@ -1,288 +1,288 @@
<?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-crm-resource"/>
</start>
<define name="element-crm-resource">
<choice>
<ref name="agents-list" />
<ref name="alternatives-list" />
<ref name="constraints-list" />
<externalRef href="generic-list-2.4.rng"/>
<element name="metadata"> <text/> </element>
<ref name="locate-list" />
<ref name="operations-list" />
<ref name="providers-list" />
<ref name="reasons-list" />
<ref name="resource-check" />
<ref name="resource-config" />
<ref name="resources-list" />
<ref name="resource-agent-action" />
</choice>
</define>
<define name="agents-list">
<element name="agents">
<attribute name="standard"> <text/> </attribute>
<optional>
<attribute name="provider"> <text/> </attribute>
</optional>
<zeroOrMore>
<element name="agent"> <text/> </element>
</zeroOrMore>
</element>
</define>
<define name="alternatives-list">
<element name="providers">
<attribute name="for"> <text/> </attribute>
<zeroOrMore>
<element name="provider"> <text/> </element>
</zeroOrMore>
</element>
</define>
<define name="constraints-list">
<element name="constraints">
<interleave>
<zeroOrMore>
<ref name="rsc-location" />
</zeroOrMore>
<zeroOrMore>
<ref name="rsc-colocation" />
</zeroOrMore>
</interleave>
</element>
</define>
<define name="locate-list">
<element name="nodes">
<attribute name="resource"> <text/> </attribute>
<zeroOrMore>
<element name="node">
<optional>
<attribute name="state"><value>promoted</value></attribute>
</optional>
<text/>
</element>
</zeroOrMore>
</element>
</define>
<define name="rsc-location">
<element name="rsc_location">
<attribute name="node"> <text/> </attribute>
<attribute name="rsc"> <text/> </attribute>
<attribute name="id"> <text/> </attribute>
<externalRef href="../score.rng"/>
</element>
</define>
<define name="operations-list">
<element name="operations">
<oneOrMore>
<ref name="element-operation-list" />
</oneOrMore>
</element>
</define>
<define name="providers-list">
<element name="providers">
<attribute name="standard"> <value>ocf</value> </attribute>
<optional>
<attribute name="agent"> <text/> </attribute>
</optional>
<zeroOrMore>
<element name="provider"> <text/> </element>
</zeroOrMore>
</element>
</define>
<define name="reasons-list">
<element name="reason">
<!-- set only when resource and node are both specified -->
<optional>
<attribute name="running_on"> <text/> </attribute>
</optional>
<!-- set only when only a resource is specified -->
<optional>
<attribute name="running"> <data type="boolean"/> </attribute>
</optional>
<choice>
<ref name="reasons-with-no-resource"/>
<ref name="resource-check"/>
</choice>
</element>
</define>
<define name="reasons-with-no-resource">
<element name="resources">
<zeroOrMore>
<element name="resource">
<attribute name="id"> <text/> </attribute>
<attribute name="running"> <data type="boolean"/> </attribute>
<optional>
<attribute name="host"> <text/> </attribute>
</optional>
<ref name="resource-check"/>
</element>
</zeroOrMore>
</element>
</define>
<define name="resource-config">
<element name="resource_config">
- <externalRef href="resources-2.28.rng" />
+ <externalRef href="resources-2.29.rng" />
<element name="xml"> <text/> </element>
</element>
</define>
<define name="resource-check">
<element name="check">
<attribute name="id"> <text/> </attribute>
<optional>
<choice>
<attribute name="remain_stopped"><value>true</value></attribute>
<attribute name="promotable"><value>false</value></attribute>
</choice>
</optional>
<optional>
<attribute name="unmanaged"><value>true</value></attribute>
</optional>
<optional>
<attribute name="locked-to"> <text/> </attribute>
</optional>
<optional>
<attribute name="unhealthy"><value>true</value></attribute>
</optional>
</element>
</define>
<define name="resources-list">
<element name="resources">
<zeroOrMore>
- <externalRef href="resources-2.28.rng" />
+ <externalRef href="resources-2.29.rng" />
</zeroOrMore>
</element>
</define>
<define name="rsc-colocation">
<element name="rsc_colocation">
<attribute name="id"> <text/> </attribute>
<attribute name="rsc"> <text/> </attribute>
<attribute name="with-rsc"> <text/> </attribute>
<externalRef href="../score.rng"/>
<optional>
<attribute name="node-attribute"> <text/> </attribute>
</optional>
<optional>
<attribute name="rsc-role">
<ref name="attribute-roles"/>
</attribute>
</optional>
<optional>
<attribute name="with-rsc-role">
<ref name="attribute-roles"/>
</attribute>
</optional>
</element>
</define>
<define name="element-operation-list">
<element name="operation">
<optional>
<group>
<attribute name="rsc"> <text/> </attribute>
<attribute name="agent"> <text/> </attribute>
</group>
</optional>
<attribute name="op"> <text/> </attribute>
<attribute name="node"> <text/> </attribute>
<attribute name="call"> <data type="integer" /> </attribute>
<attribute name="rc"> <data type="nonNegativeInteger" /> </attribute>
<optional>
<attribute name="last-rc-change"> <text/> </attribute>
<attribute name="exec-time"> <data type="nonNegativeInteger" /> </attribute>
</optional>
<attribute name="status"> <text/> </attribute>
</element>
</define>
<define name="resource-agent-action">
<element name="resource-agent-action">
<attribute name="action"> <text/> </attribute>
<optional>
<attribute name="rsc"> <text/> </attribute>
</optional>
<attribute name="class"> <text/> </attribute>
<attribute name="type"> <text/> </attribute>
<optional>
<attribute name="provider"> <text/> </attribute>
</optional>
<optional>
<ref name="overrides-list"/>
</optional>
<ref name="agent-status"/>
<optional>
<element name="command">
<choice>
<text />
<externalRef href="subprocess-output-2.23.rng"/>
</choice>
</element>
</optional>
</element>
</define>
<define name="overrides-list">
<element name="overrides">
<zeroOrMore>
<element name="override">
<optional>
<attribute name="rsc"> <text/> </attribute>
</optional>
<attribute name="name"> <text/> </attribute>
<attribute name="value"> <text/> </attribute>
</element>
</zeroOrMore>
</element>
</define>
<define name="agent-status">
<element name="agent-status">
<attribute name="code"> <data type="integer" /> </attribute>
<optional>
<attribute name="message"> <text/> </attribute>
</optional>
<optional>
<attribute name="execution_code"> <data type="integer" /> </attribute>
</optional>
<optional>
<attribute name="execution_message"> <text/> </attribute>
</optional>
<optional>
<attribute name="reason"> <text/> </attribute>
</optional>
</element>
</define>
<define name="attribute-roles">
<choice>
<value>Stopped</value>
<value>Started</value>
<value>Promoted</value>
<value>Unpromoted</value>
<!-- These synonyms for Promoted/Unpromoted are allowed for
backward compatibility with output from older Pacemaker
versions that used them -->
<value>Master</value>
<value>Slave</value>
</choice>
</define>
</grammar>
diff --git a/xml/api/crm_simulate-2.29.rng b/xml/api/crm_simulate-2.29.rng
index 58be93d705..48cf942f67 100644
--- a/xml/api/crm_simulate-2.29.rng
+++ b/xml/api/crm_simulate-2.29.rng
@@ -1,338 +1,338 @@
<?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-crm-simulate"/>
</start>
<define name="element-crm-simulate">
<choice>
<ref name="timings-list" />
<group>
<ref name="cluster-status" />
<optional>
<ref name="modifications-list" />
</optional>
<optional>
<ref name="allocations-utilizations-list" />
</optional>
<optional>
<ref name="action-list" />
</optional>
<optional>
<ref name="cluster-injected-actions-list" />
<ref name="revised-cluster-status" />
</optional>
</group>
</choice>
</define>
<define name="allocations-utilizations-list">
<choice>
<element name="allocations">
<zeroOrMore>
<choice>
<ref name="element-allocation" />
<ref name="element-promotion" />
</choice>
</zeroOrMore>
</element>
<element name="utilizations">
<zeroOrMore>
<choice>
<ref name="element-capacity" />
<ref name="element-utilization" />
</choice>
</zeroOrMore>
</element>
<element name="allocations_utilizations">
<zeroOrMore>
<choice>
<ref name="element-allocation" />
<ref name="element-promotion" />
<ref name="element-capacity" />
<ref name="element-utilization" />
</choice>
</zeroOrMore>
</element>
</choice>
</define>
<define name="cluster-status">
<element name="cluster_status">
<ref name="nodes-list" />
<ref name="resources-list" />
<optional>
<ref name="node-attributes-list" />
</optional>
<optional>
<externalRef href="node-history-2.12.rng" />
</optional>
<optional>
<ref name="failures-list" />
</optional>
</element>
</define>
<define name="modifications-list">
<element name="modifications">
<optional>
<attribute name="quorum"> <text /> </attribute>
</optional>
<optional>
<attribute name="watchdog"> <text /> </attribute>
</optional>
<zeroOrMore>
<ref name="element-inject-modify-node" />
</zeroOrMore>
<zeroOrMore>
<ref name="element-inject-modify-ticket" />
</zeroOrMore>
<zeroOrMore>
<ref name="element-inject-spec" />
</zeroOrMore>
<zeroOrMore>
<ref name="element-inject-attr" />
</zeroOrMore>
</element>
</define>
<define name="revised-cluster-status">
<element name="revised_cluster_status">
<ref name="nodes-list" />
<ref name="resources-list" />
<optional>
<ref name="node-attributes-list" />
</optional>
<optional>
<ref name="failures-list" />
</optional>
</element>
</define>
<define name="element-inject-attr">
<element name="inject_attr">
<attribute name="cib_node"> <text /> </attribute>
<attribute name="name"> <text /> </attribute>
<attribute name="node_path"> <text /> </attribute>
<attribute name="value"> <text /> </attribute>
</element>
</define>
<define name="element-inject-modify-node">
<element name="modify_node">
<attribute name="action"> <text /> </attribute>
<attribute name="node"> <text /> </attribute>
</element>
</define>
<define name="element-inject-spec">
<element name="inject_spec">
<attribute name="spec"> <text /> </attribute>
</element>
</define>
<define name="element-inject-modify-ticket">
<element name="modify_ticket">
<attribute name="action"> <text /> </attribute>
<attribute name="ticket"> <text /> </attribute>
</element>
</define>
<define name="cluster-injected-actions-list">
<element name="transition">
<zeroOrMore>
<ref name="element-injected-actions" />
</zeroOrMore>
</element>
</define>
<define name="node-attributes-list">
<element name="node_attributes">
<zeroOrMore>
<externalRef href="node-attrs-2.8.rng" />
</zeroOrMore>
</element>
</define>
<define name="failures-list">
<element name="failures">
<zeroOrMore>
<externalRef href="failure-2.8.rng" />
</zeroOrMore>
</element>
</define>
<define name="nodes-list">
<element name="nodes">
<zeroOrMore>
- <externalRef href="nodes-2.28.rng" />
+ <externalRef href="nodes-2.29.rng" />
</zeroOrMore>
</element>
</define>
<define name="resources-list">
<element name="resources">
<zeroOrMore>
- <externalRef href="resources-2.28.rng" />
+ <externalRef href="resources-2.29.rng" />
</zeroOrMore>
</element>
</define>
<define name="timings-list">
<element name="timings">
<zeroOrMore>
<ref name="element-timing" />
</zeroOrMore>
</element>
</define>
<define name="action-list">
<element name="actions">
<zeroOrMore>
<ref name="element-node-action" />
</zeroOrMore>
<zeroOrMore>
<ref name="element-rsc-action" />
</zeroOrMore>
</element>
</define>
<define name="element-allocation">
<element name="node_weight">
<attribute name="function"> <text /> </attribute>
<attribute name="node"> <text /> </attribute>
<externalRef href="../score.rng" />
<optional>
<attribute name="id"> <text /> </attribute>
</optional>
</element>
</define>
<define name="element-capacity">
<element name="capacity">
<attribute name="comment"> <text /> </attribute>
<attribute name="node"> <text /> </attribute>
<zeroOrMore>
<element>
<anyName />
<text />
</element>
</zeroOrMore>
</element>
</define>
<define name="element-inject-cluster-action">
<element name="cluster_action">
<attribute name="node"> <text /> </attribute>
<attribute name="task"> <text /> </attribute>
<optional>
<attribute name="id"> <text /> </attribute>
</optional>
</element>
</define>
<define name="element-injected-actions">
<choice>
<ref name="element-inject-cluster-action" />
<ref name="element-inject-fencing-action" />
<ref name="element-inject-pseudo-action" />
<ref name="element-inject-rsc-action" />
</choice>
</define>
<define name="element-inject-fencing-action">
<element name="fencing_action">
<attribute name="op"> <text /> </attribute>
<attribute name="target"> <text /> </attribute>
</element>
</define>
<define name="element-node-action">
<element name="node_action">
<attribute name="node"> <text /> </attribute>
<attribute name="reason"> <text /> </attribute>
<attribute name="task"> <text /> </attribute>
</element>
</define>
<define name="element-promotion">
<element name="promotion_score">
<attribute name="id"> <text /> </attribute>
<externalRef href="../score.rng" />
<optional>
<attribute name="node"> <text /> </attribute>
</optional>
</element>
</define>
<define name="element-inject-pseudo-action">
<element name="pseudo_action">
<attribute name="task"> <text /> </attribute>
<optional>
<attribute name="node"> <text /> </attribute>
</optional>
</element>
</define>
<define name="element-inject-rsc-action">
<element name="rsc_action">
<attribute name="node"> <text /> </attribute>
<attribute name="op"> <text /> </attribute>
<attribute name="resource"> <text /> </attribute>
<optional>
<attribute name="interval"> <data type="integer" /> </attribute>
</optional>
</element>
</define>
<define name="element-timing">
<element name="timing">
<attribute name="file"> <text /> </attribute>
<attribute name="duration"> <data type="double" /> </attribute>
</element>
</define>
<define name="element-rsc-action">
<element name="rsc_action">
<attribute name="action"> <text /> </attribute>
<attribute name="resource"> <text /> </attribute>
<optional>
<attribute name="blocked"> <data type="boolean" /> </attribute>
</optional>
<optional>
<attribute name="dest"> <text /> </attribute>
</optional>
<optional>
<attribute name="next-role"> <text /> </attribute>
</optional>
<optional>
<attribute name="node"> <text /> </attribute>
</optional>
<optional>
<attribute name="reason"> <text /> </attribute>
</optional>
<optional>
<attribute name="role"> <text /> </attribute>
</optional>
<optional>
<attribute name="source"> <text /> </attribute>
</optional>
</element>
</define>
<define name="element-utilization">
<element name="utilization">
<attribute name="function"> <text /> </attribute>
<attribute name="node"> <text /> </attribute>
<attribute name="resource"> <text /> </attribute>
<zeroOrMore>
<element>
<anyName />
<text />
</element>
</zeroOrMore>
</element>
</define>
</grammar>
diff --git a/xml/api/nodes-2.29.rng b/xml/api/nodes-2.29.rng
index 19b5c09cc0..7dd1798914 100644
--- a/xml/api/nodes-2.29.rng
+++ b/xml/api/nodes-2.29.rng
@@ -1,54 +1,54 @@
<?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-full-node"/>
</start>
<define name="element-full-node">
<element name="node">
<attribute name="name"> <text/> </attribute>
<attribute name="id"> <text/> </attribute>
<attribute name="online"> <data type="boolean" /> </attribute>
<attribute name="standby"> <data type="boolean" /> </attribute>
<attribute name="standby_onfail"> <data type="boolean" /> </attribute>
<attribute name="maintenance"> <data type="boolean" /> </attribute>
<attribute name="pending"> <data type="boolean" /> </attribute>
<attribute name="unclean"> <data type="boolean" /> </attribute>
<optional>
<attribute name="health">
<choice>
<value>red</value>
<value>yellow</value>
<value>green</value>
</choice>
</attribute>
</optional>
<optional>
<attribute name="feature_set"> <text/> </attribute>
</optional>
<attribute name="shutdown"> <data type="boolean" /> </attribute>
<attribute name="expected_up"> <data type="boolean" /> </attribute>
<attribute name="is_dc"> <data type="boolean" /> </attribute>
<attribute name="resources_running"> <data type="nonNegativeInteger" /> </attribute>
<attribute name="type">
<choice>
<value>unknown</value>
<value>member</value>
<value>remote</value>
<value>ping</value>
</choice>
</attribute>
<optional>
<!-- for virtualized pacemaker_remote nodes, crm_mon 1.1.13 uses
"container_id" while later versions use "id_as_resource" -->
<choice>
<attribute name="container_id"> <text/> </attribute>
<attribute name="id_as_resource"> <text/> </attribute>
</choice>
</optional>
- <externalRef href="resources-2.28.rng" />
+ <externalRef href="resources-2.29.rng" />
</element>
</define>
</grammar>
diff --git a/xml/api/resources-2.29.rng b/xml/api/resources-2.29.rng
index 3a79bfd7f8..f4214a7c64 100644
--- a/xml/api/resources-2.29.rng
+++ b/xml/api/resources-2.29.rng
@@ -1,132 +1,152 @@
<?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-resource-list"/>
</start>
<define name="element-resource-list">
<interleave>
<zeroOrMore>
<ref name="element-bundle" />
</zeroOrMore>
<zeroOrMore>
<ref name="element-clone" />
</zeroOrMore>
<zeroOrMore>
<ref name="element-group" />
</zeroOrMore>
<zeroOrMore>
<ref name="element-resource" />
</zeroOrMore>
</interleave>
</define>
<define name="element-bundle">
<element name="bundle">
<attribute name="id"> <text/> </attribute>
<attribute name="type">
<choice>
<value>docker</value>
<value>rkt</value>
<value>podman</value>
</choice>
</attribute>
<attribute name="image"> <text/> </attribute>
<attribute name="unique"> <data type="boolean" /> </attribute>
<optional>
<attribute name="maintenance">
<data type="boolean" />
</attribute>
</optional>
+ <optional>
+ <attribute name="description">
+ <text/>
+ </attribute>
+ </optional>
<attribute name="managed"> <data type="boolean" /> </attribute>
<attribute name="failed"> <data type="boolean" /> </attribute>
<zeroOrMore>
<element name="replica">
<attribute name="id"> <data type="nonNegativeInteger" /> </attribute>
<zeroOrMore>
<ref name="element-resource" />
</zeroOrMore>
</element>
</zeroOrMore>
</element>
</define>
<define name="element-clone">
<element name="clone">
<attribute name="id"> <text/> </attribute>
<attribute name="multi_state"> <data type="boolean" /> </attribute>
<attribute name="unique"> <data type="boolean" /> </attribute>
<optional>
<attribute name="maintenance">
<data type="boolean" />
</attribute>
</optional>
+ <optional>
+ <attribute name="description">
+ <text/>
+ </attribute>
+ </optional>
<attribute name="managed"> <data type="boolean" /> </attribute>
<attribute name="disabled"> <data type="boolean" /> </attribute>
<attribute name="failed"> <data type="boolean" /> </attribute>
<attribute name="failure_ignored"> <data type="boolean" /> </attribute>
<optional>
<attribute name="target_role"> <text/> </attribute>
</optional>
<ref name="element-resource-list" />
</element>
</define>
<define name="element-group">
<element name="group">
<attribute name="id"> <text/> </attribute>
<attribute name="number_resources"> <data type="nonNegativeInteger" /> </attribute>
<optional>
<attribute name="maintenance">
<data type="boolean" />
</attribute>
</optional>
+ <optional>
+ <attribute name="description">
+ <text/>
+ </attribute>
+ </optional>
<attribute name="managed"> <data type="boolean" /> </attribute>
<attribute name="disabled"> <data type="boolean" /> </attribute>
<ref name="element-resource-list" />
</element>
</define>
<define name="element-resource">
<element name="resource">
<attribute name="id"> <text/> </attribute>
<attribute name="resource_agent"> <text/> </attribute>
<attribute name="role"> <text/> </attribute>
<optional>
<attribute name="target_role"> <text/> </attribute>
</optional>
<attribute name="active"> <data type="boolean" /> </attribute>
<attribute name="orphaned"> <data type="boolean" /> </attribute>
<optional>
<attribute name="blocked"> <data type="boolean" /> </attribute>
</optional>
<optional>
<attribute name="maintenance">
<data type="boolean" />
</attribute>
</optional>
+ <optional>
+ <attribute name="description">
+ <text/>
+ </attribute>
+ </optional>
<attribute name="failed"> <data type="boolean" /> </attribute>
<attribute name="managed"> <data type="boolean" /> </attribute>
<attribute name="failure_ignored"> <data type="boolean" /> </attribute>
<attribute name="nodes_running_on"> <data type="nonNegativeInteger" /> </attribute>
<optional>
<attribute name="pending"> <text/> </attribute>
</optional>
<optional>
<attribute name="locked_to"> <text/> </attribute>
</optional>
<zeroOrMore>
<element name="node">
<attribute name="name"> <text/> </attribute>
<attribute name="id"> <text/> </attribute>
<attribute name="cached"> <data type="boolean" /> </attribute>
</element>
</zeroOrMore>
<optional>
<element name="xml"> <text/> </element>
</optional>
</element>
</define>
</grammar>

File Metadata

Mime Type
text/x-diff
Expires
Sat, Nov 23, 12:03 PM (21 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1018699
Default Alt Text
(74 KB)

Event Timeline