root/include/crm/common/xml.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. crm_map_element_name
  2. numXpathResults

   1 /*
   2  * Copyright 2004-2023 the Pacemaker project contributors
   3  *
   4  * The version control history for this file may have further details.
   5  *
   6  * This source code is licensed under the GNU Lesser General Public License
   7  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
   8  */
   9 
  10 #ifndef PCMK__CRM_COMMON_XML__H
  11 #  define PCMK__CRM_COMMON_XML__H
  12 
  13 
  14 #  include <stdio.h>
  15 #  include <sys/types.h>
  16 #  include <unistd.h>
  17 
  18 #  include <stdlib.h>
  19 #  include <errno.h>
  20 #  include <fcntl.h>
  21 
  22 #  include <libxml/tree.h>
  23 #  include <libxml/xpath.h>
  24 
  25 #  include <crm/crm.h>
  26 #  include <crm/common/nvpair.h>
  27 
  28 #ifdef __cplusplus
  29 extern "C" {
  30 #endif
  31 
  32 /**
  33  * \file
  34  * \brief Wrappers for and extensions to libxml2
  35  * \ingroup core
  36  */
  37 
  38 /* Define compression parameters for IPC messages
  39  *
  40  * Compression costs a LOT, so we don't want to do it unless we're hitting
  41  * message limits. Currently, we use 128KB as the threshold, because higher
  42  * values don't play well with the heartbeat stack. With an earlier limit of
  43  * 10KB, compressing 184 of 1071 messages accounted for 23% of the total CPU
  44  * used by the cib.
  45  */
  46 #  define CRM_BZ2_BLOCKS                4
  47 #  define CRM_BZ2_WORK          20
  48 #  define CRM_BZ2_THRESHOLD     128 * 1024
  49 
  50 typedef const xmlChar *pcmkXmlStr;
  51 
  52 gboolean add_message_xml(xmlNode * msg, const char *field, xmlNode * xml);
  53 xmlNode *get_message_xml(const xmlNode *msg, const char *field);
  54 
  55 /*
  56  * \brief xmlCopyPropList ACLs-sensitive replacement expading i++ notation
  57  *
  58  * The gist is the same as with \c{xmlCopyPropList(target, src->properties)}.
  59  * The function exits prematurely when any attribute cannot be copied for
  60  * ACLs violation.  Even without bailing out, the result can possibly be
  61  * incosistent with expectations in that case, hence the caller shall,
  62  * aposteriori, verify that no document-level-tracked denial was indicated
  63  * with \c{xml_acl_denied(target)} and drop whole such intermediate object.
  64  *
  65  * \param[in,out] target  Element to receive attributes from #src element
  66  * \param[in]     src     Element carrying attributes to copy over to #target
  67  *
  68  * \note Original commit 1c632c506 sadly haven't stated which otherwise
  69  *       assumed behaviours of xmlCopyPropList were missing beyond otherwise
  70  *       custom extensions like said ACLs and "atomic increment" (that landed
  71  *       later on, anyway).
  72  */
  73 void copy_in_properties(xmlNode *target, const xmlNode *src);
  74 
  75 void expand_plus_plus(xmlNode * target, const char *name, const char *value);
  76 void fix_plus_plus_recursive(xmlNode * target);
  77 
  78 /*
  79  * Create a node named "name" as a child of "parent"
  80  * If parent is NULL, creates an unconnected node.
  81  *
  82  * Returns the created node
  83  *
  84  */
  85 xmlNode *create_xml_node(xmlNode * parent, const char *name);
  86 
  87 /*
  88  * Create a node named "name" as a child of "parent", giving it the provided
  89  * text content.
  90  * If parent is NULL, creates an unconnected node.
  91  *
  92  * Returns the created node
  93  *
  94  */
  95 xmlNode *pcmk_create_xml_text_node(xmlNode * parent, const char *name, const char *content);
  96 
  97 /*
  98  * Create a new HTML node named "element_name" as a child of "parent", giving it the
  99  * provided text content.  Optionally, apply a CSS #id and #class.
 100  *
 101  * Returns the created node.
 102  */
 103 xmlNode *pcmk_create_html_node(xmlNode * parent, const char *element_name, const char *id,
 104                                const char *class_name, const char *text);
 105 
 106 /*
 107  *
 108  */
 109 void purge_diff_markers(xmlNode * a_node);
 110 
 111 /*
 112  * Returns a deep copy of src_node
 113  *
 114  */
 115 xmlNode *copy_xml(xmlNode * src_node);
 116 
 117 /*
 118  * Add a copy of xml_node to new_parent
 119  */
 120 xmlNode *add_node_copy(xmlNode * new_parent, xmlNode * xml_node);
 121 
 122 /*
 123  * XML I/O Functions
 124  *
 125  * Whitespace between tags is discarded.
 126  */
 127 xmlNode *filename2xml(const char *filename);
 128 
 129 xmlNode *stdin2xml(void);
 130 
 131 xmlNode *string2xml(const char *input);
 132 
 133 int write_xml_fd(const xmlNode *xml, const char *filename, int fd,
 134                  gboolean compress);
 135 int write_xml_file(const xmlNode *xml, const char *filename, gboolean compress);
 136 
 137 char *dump_xml_formatted(const xmlNode *xml);
 138 char *dump_xml_formatted_with_text(const xmlNode *xml);
 139 char *dump_xml_unformatted(const xmlNode *xml);
 140 
 141 /*
 142  * Diff related Functions
 143  */
 144 xmlNode *diff_xml_object(xmlNode * left, xmlNode * right, gboolean suppress);
 145 
 146 xmlNode *subtract_xml_object(xmlNode * parent, xmlNode * left, xmlNode * right,
 147                              gboolean full, gboolean * changed, const char *marker);
 148 
 149 gboolean can_prune_leaf(xmlNode * xml_node);
 150 
 151 /*
 152  * Searching & Modifying
 153  */
 154 xmlNode *find_xml_node(const xmlNode *root, const char *search_path,
 155                        gboolean must_find);
 156 
 157 void xml_remove_prop(xmlNode * obj, const char *name);
 158 
 159 gboolean replace_xml_child(xmlNode * parent, xmlNode * child, xmlNode * update,
 160                            gboolean delete_only);
 161 
 162 gboolean update_xml_child(xmlNode * child, xmlNode * to_update);
 163 
 164 int find_xml_children(xmlNode ** children, xmlNode * root,
 165                       const char *tag, const char *field, const char *value,
 166                       gboolean search_matches);
 167 
 168 xmlNode *get_xpath_object(const char *xpath, xmlNode * xml_obj, int error_level);
 169 xmlNode *get_xpath_object_relative(const char *xpath, xmlNode * xml_obj, int error_level);
 170 
 171 static inline const char *
 172 crm_map_element_name(const xmlNode *xml)
     /* [previous][next][first][last][top][bottom][index][help] */
 173 {
 174     if (xml == NULL) {
 175         return NULL;
 176     } else if (strcmp((const char *) xml->name, "master") == 0) {
 177         return "clone";
 178     } else {
 179         return (const char *) xml->name;
 180     }
 181 }
 182 
 183 char *calculate_on_disk_digest(xmlNode * local_cib);
 184 char *calculate_operation_digest(xmlNode * local_cib, const char *version);
 185 char *calculate_xml_versioned_digest(xmlNode * input, gboolean sort, gboolean do_filter,
 186                                      const char *version);
 187 
 188 /* schema-related functions (from schemas.c) */
 189 gboolean validate_xml(xmlNode * xml_blob, const char *validation, gboolean to_logs);
 190 gboolean validate_xml_verbose(const xmlNode *xml_blob);
 191 
 192 /*!
 193  * \brief Update CIB XML to most recent schema version
 194  *
 195  * "Update" means either actively employ XSLT-based transformation(s)
 196  * (if intermediate product to transform valid per its declared schema version,
 197  * transformation available, proceeded successfully with a result valid per
 198  * expectated newer schema version), or just try to bump the marked validating
 199  * schema until all gradually rising schema versions attested or the first
 200  * such attempt subsequently fails to validate.   Which of the two styles will
 201  * be used depends on \p transform parameter (positive/negative, respectively).
 202  *
 203  * \param[in,out] xml_blob   XML tree representing CIB, may be swapped with
 204  *                           an "updated" one
 205  * \param[out]    best       The highest configuration version (per its index
 206  *                           in the global schemas table) it was possible to
 207  *                           reach during the update steps while ensuring
 208  *                           the validity of the result; if no validation
 209  *                           success was observed against possibly multiple
 210  *                           schemas, the value is less or equal the result
 211  *                           of \c get_schema_version applied on the input
 212  *                           \p xml_blob value (unless that function maps it
 213  *                           to -1, then 0 would be used instead)
 214  * \param[in]     max        When \p transform is positive, this allows to
 215  *                           set upper boundary schema (per its index in the
 216  *                           global schemas table) beyond which it's forbidden
 217  *                           to update by the means of XSLT transformation
 218  * \param[in]     transform  Whether to employ XSLT-based transformation so
 219  *                           as to allow overcoming possible incompatibilities
 220  *                           between major schema versions (see above)
 221  * \param[in]     to_logs    If true, output notable progress info to
 222  *                           internal log streams; if false, to stderr
 223  *
 224  * \return \c pcmk_ok if no non-recoverable error encountered (up to
 225  *         caller to evaluate if the update satisfies the requirements
 226  *         per returned \p best value), negative value carrying the reason
 227  *         otherwise
 228  */
 229 int update_validation(xmlNode **xml_blob, int *best, int max,
 230                       gboolean transform, gboolean to_logs);
 231 
 232 int get_schema_version(const char *name);
 233 const char *get_schema_name(int version);
 234 const char *xml_latest_schema(void);
 235 gboolean cli_config_update(xmlNode ** xml, int *best_version, gboolean to_logs);
 236 
 237 /*!
 238  * \brief Initialize the CRM XML subsystem
 239  *
 240  * This method sets global XML settings and loads pacemaker schemas into the cache.
 241  */
 242 void crm_xml_init(void);
 243 void crm_xml_cleanup(void);
 244 
 245 void pcmk_free_xml_subtree(xmlNode *xml);
 246 void free_xml(xmlNode * child);
 247 
 248 xmlNode *first_named_child(const xmlNode *parent, const char *name);
 249 xmlNode *crm_next_same_xml(const xmlNode *sibling);
 250 
 251 xmlNode *sorted_xml(xmlNode * input, xmlNode * parent, gboolean recursive);
 252 xmlXPathObjectPtr xpath_search(const xmlNode *xml_top, const char *path);
 253 void crm_foreach_xpath_result(xmlNode *xml, const char *xpath,
 254                               void (*helper)(xmlNode*, void*), void *user_data);
 255 xmlNode *expand_idref(xmlNode * input, xmlNode * top);
 256 
 257 void freeXpathObject(xmlXPathObjectPtr xpathObj);
 258 xmlNode *getXpathResult(xmlXPathObjectPtr xpathObj, int index);
 259 void dedupXpathResults(xmlXPathObjectPtr xpathObj);
 260 
 261 static inline int numXpathResults(xmlXPathObjectPtr xpathObj)
     /* [previous][next][first][last][top][bottom][index][help] */
 262 {
 263     if(xpathObj == NULL || xpathObj->nodesetval == NULL) {
 264         return 0;
 265     }
 266     return xpathObj->nodesetval->nodeNr;
 267 }
 268 
 269 bool xml_tracking_changes(xmlNode * xml);
 270 bool xml_document_dirty(xmlNode *xml);
 271 void xml_track_changes(xmlNode * xml, const char *user, xmlNode *acl_source, bool enforce_acls);
 272 void xml_calculate_changes(xmlNode *old_xml, xmlNode *new_xml);
 273 void xml_calculate_significant_changes(xmlNode *old_xml, xmlNode *new_xml);
 274 void xml_accept_changes(xmlNode * xml);
 275 bool xml_patch_versions(const xmlNode *patchset, int add[3], int del[3]);
 276 
 277 xmlNode *xml_create_patchset(
 278     int format, xmlNode *source, xmlNode *target, bool *config, bool manage_version);
 279 int xml_apply_patchset(xmlNode *xml, xmlNode *patchset, bool check_version);
 280 
 281 void patchset_process_digest(xmlNode *patch, xmlNode *source, xmlNode *target, bool with_digest);
 282 
 283 void save_xml_to_file(const xmlNode *xml, const char *desc,
 284                       const char *filename);
 285 
 286 char * crm_xml_escape(const char *text);
 287 void crm_xml_sanitize_id(char *id);
 288 void crm_xml_set_id(xmlNode *xml, const char *format, ...) G_GNUC_PRINTF(2, 3);
 289 
 290 #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
 291 #include <crm/common/xml_compat.h>
 292 #endif
 293 
 294 #ifdef __cplusplus
 295 }
 296 #endif
 297 
 298 #endif

/* [previous][next][first][last][top][bottom][index][help] */