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_element_name
  2. crm_map_element_name
  3. numXpathResults

   1 /*
   2  * Copyright 2004-2020 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 CRM_COMMON_XML__H
  11 #  define CRM_COMMON_XML__H
  12 
  13 #ifdef __cplusplus
  14 extern "C" {
  15 #endif
  16 
  17 /**
  18  * \file
  19  * \brief Wrappers for and extensions to libxml2
  20  * \ingroup core
  21  */
  22 
  23 #  include <stdio.h>
  24 #  include <sys/types.h>
  25 #  include <unistd.h>
  26 
  27 #  include <stdlib.h>
  28 #  include <errno.h>
  29 #  include <fcntl.h>
  30 
  31 #  include <libxml/tree.h>
  32 #  include <libxml/xpath.h>
  33 
  34 #  include <crm/crm.h>
  35 #  include <crm/common/nvpair.h>
  36 
  37 /* Define compression parameters for IPC messages
  38  *
  39  * Compression costs a LOT, so we don't want to do it unless we're hitting
  40  * message limits. Currently, we use 128KB as the threshold, because higher
  41  * values don't play well with the heartbeat stack. With an earlier limit of
  42  * 10KB, compressing 184 of 1071 messages accounted for 23% of the total CPU
  43  * used by the cib.
  44  */
  45 #  define CRM_BZ2_BLOCKS                4
  46 #  define CRM_BZ2_WORK          20
  47 #  define CRM_BZ2_THRESHOLD     128 * 1024
  48 
  49 #  define XML_PARANOIA_CHECKS 0
  50 
  51 typedef const xmlChar *pcmkXmlStr;
  52 
  53 gboolean add_message_xml(xmlNode * msg, const char *field, xmlNode * xml);
  54 xmlNode *get_message_xml(xmlNode * msg, const char *field);
  55 
  56 xmlDoc *getDocPtr(xmlNode * node);
  57 
  58 /*
  59  * Replacement function for xmlCopyPropList which at the very least,
  60  * doesn't work the way *I* would expect it to.
  61  *
  62  * Copy all the attributes/properties from src into target.
  63  *
  64  * Not recursive, does not return anything.
  65  *
  66  */
  67 void copy_in_properties(xmlNode * target, xmlNode * src);
  68 void expand_plus_plus(xmlNode * target, const char *name, const char *value);
  69 void fix_plus_plus_recursive(xmlNode * target);
  70 
  71 /*
  72  * Create a node named "name" as a child of "parent"
  73  * If parent is NULL, creates an unconnected node.
  74  *
  75  * Returns the created node
  76  *
  77  */
  78 xmlNode *create_xml_node(xmlNode * parent, const char *name);
  79 
  80 /*
  81  * Create a node named "name" as a child of "parent", giving it the provided
  82  * text content.
  83  * If parent is NULL, creates an unconnected node.
  84  *
  85  * Returns the created node
  86  *
  87  */
  88 xmlNode *pcmk_create_xml_text_node(xmlNode * parent, const char *name, const char *content);
  89 
  90 /*
  91  * Create a new HTML node named "element_name" as a child of "parent", giving it the
  92  * provided text content.  Optionally, apply a CSS #id and #class.
  93  *
  94  * Returns the created node.
  95  */
  96 xmlNode *pcmk_create_html_node(xmlNode * parent, const char *element_name, const char *id,
  97                                const char *class_name, const char *text);
  98 
  99 /*
 100  *
 101  */
 102 void purge_diff_markers(xmlNode * a_node);
 103 
 104 /*
 105  * Returns a deep copy of src_node
 106  *
 107  */
 108 xmlNode *copy_xml(xmlNode * src_node);
 109 
 110 /*
 111  * Add a copy of xml_node to new_parent
 112  */
 113 xmlNode *add_node_copy(xmlNode * new_parent, xmlNode * xml_node);
 114 
 115 int add_node_nocopy(xmlNode * parent, const char *name, xmlNode * child);
 116 
 117 /*
 118  * XML I/O Functions
 119  *
 120  * Whitespace between tags is discarded.
 121  */
 122 xmlNode *filename2xml(const char *filename);
 123 
 124 xmlNode *stdin2xml(void);
 125 
 126 xmlNode *string2xml(const char *input);
 127 
 128 int write_xml_fd(xmlNode * xml_node, const char *filename, int fd, gboolean compress);
 129 int write_xml_file(xmlNode * xml_node, const char *filename, gboolean compress);
 130 
 131 char *dump_xml_formatted(xmlNode * msg);
 132 /* Also dump the text node with xml_log_option_text enabled */ 
 133 char *dump_xml_formatted_with_text(xmlNode * msg);
 134 
 135 char *dump_xml_unformatted(xmlNode * msg);
 136 
 137 /*
 138  * Diff related Functions
 139  */
 140 xmlNode *diff_xml_object(xmlNode * left, xmlNode * right, gboolean suppress);
 141 
 142 xmlNode *subtract_xml_object(xmlNode * parent, xmlNode * left, xmlNode * right,
 143                              gboolean full, gboolean * changed, const char *marker);
 144 
 145 gboolean can_prune_leaf(xmlNode * xml_node);
 146 
 147 /*
 148  * Searching & Modifying
 149  */
 150 xmlNode *find_xml_node(xmlNode * cib, const char *node_path, gboolean must_find);
 151 
 152 void xml_remove_prop(xmlNode * obj, const char *name);
 153 
 154 gboolean replace_xml_child(xmlNode * parent, xmlNode * child, xmlNode * update,
 155                            gboolean delete_only);
 156 
 157 gboolean update_xml_child(xmlNode * child, xmlNode * to_update);
 158 
 159 int find_xml_children(xmlNode ** children, xmlNode * root,
 160                       const char *tag, const char *field, const char *value,
 161                       gboolean search_matches);
 162 
 163 xmlNode *get_xpath_object(const char *xpath, xmlNode * xml_obj, int error_level);
 164 xmlNode *get_xpath_object_relative(const char *xpath, xmlNode * xml_obj, int error_level);
 165 
 166 static inline const char *
 167 crm_element_name(const xmlNode *xml)
     /* [previous][next][first][last][top][bottom][index][help] */
 168 {
 169     return xml? (const char *)(xml->name) : NULL;
 170 }
 171 
 172 static inline const char *
 173 crm_map_element_name(const xmlNode *xml)
     /* [previous][next][first][last][top][bottom][index][help] */
 174 {
 175     const char *name = crm_element_name(xml);
 176 
 177     if (strcmp(name, "master") == 0) {
 178         return "clone";
 179     } else {
 180         return name;
 181     }
 182 }
 183 
 184 gboolean xml_has_children(const xmlNode * root);
 185 
 186 char *calculate_on_disk_digest(xmlNode * local_cib);
 187 char *calculate_operation_digest(xmlNode * local_cib, const char *version);
 188 char *calculate_xml_versioned_digest(xmlNode * input, gboolean sort, gboolean do_filter,
 189                                      const char *version);
 190 
 191 /* schema-related functions (from schemas.c) */
 192 gboolean validate_xml(xmlNode * xml_blob, const char *validation, gboolean to_logs);
 193 gboolean validate_xml_verbose(xmlNode * xml_blob);
 194 
 195 /*!
 196  * \brief Update CIB XML to most recent schema version
 197  *
 198  * "Update" means either actively employ XSLT-based transformation(s)
 199  * (if intermediate product to transform valid per its declared schema version,
 200  * transformation available, proceeded successfully with a result valid per
 201  * expectated newer schema version), or just try to bump the marked validating
 202  * schema until all gradually rising schema versions attested or the first
 203  * such attempt subsequently fails to validate.   Which of the two styles will
 204  * be used depends on \p transform parameter (positive/negative, respectively).
 205  *
 206  * \param[in,out] xml_blob   XML tree representing CIB, may be swapped with
 207  *                           an "updated" one
 208  * \param[out]    best       The highest configuration version (per its index
 209  *                           in the global schemas table) it was possible to
 210  *                           reach during the update steps while ensuring
 211  *                           the validity of the result; if no validation
 212  *                           success was observed against possibly multiple
 213  *                           schemas, the value is less or equal the result
 214  *                           of \c get_schema_version applied on the input
 215  *                           \p xml_blob value (unless that function maps it
 216  *                           to -1, then 0 would be used instead)
 217  * \param[in]     max        When \p transform is positive, this allows to
 218  *                           set upper boundary schema (per its index in the
 219  *                           global schemas table) beyond which it's forbidden
 220  *                           to update by the means of XSLT transformation
 221  * \param[in]     transform  Whether to employ XSLT-based transformation so
 222  *                           as to allow overcoming possible incompatibilities
 223  *                           between major schema versions (see above)
 224  * \param[in]     to_logs    If true, output notable progress info to
 225  *                           internal log streams; if false, to stderr
 226  *
 227  * \return \c pcmk_ok if no non-recoverable error encountered (up to
 228  *         caller to evaluate if the update satisfies the requirements
 229  *         per returned \p best value), negative value carrying the reason
 230  *         otherwise
 231  */
 232 int update_validation(xmlNode **xml_blob, int *best, int max,
 233                       gboolean transform, gboolean to_logs);
 234 
 235 int get_schema_version(const char *name);
 236 const char *get_schema_name(int version);
 237 const char *xml_latest_schema(void);
 238 gboolean cli_config_update(xmlNode ** xml, int *best_version, gboolean to_logs);
 239 
 240 void crm_xml_init(void);
 241 void crm_xml_cleanup(void);
 242 
 243 void pcmk_free_xml_subtree(xmlNode *xml);
 244 void free_xml(xmlNode * child);
 245 
 246 xmlNode *first_named_child(const xmlNode *parent, const char *name);
 247 xmlNode *crm_next_same_xml(const xmlNode *sibling);
 248 
 249 xmlNode *sorted_xml(xmlNode * input, xmlNode * parent, gboolean recursive);
 250 xmlXPathObjectPtr xpath_search(xmlNode * xml_top, const char *path);
 251 void crm_foreach_xpath_result(xmlNode *xml, const char *xpath,
 252                               void (*helper)(xmlNode*, void*), void *user_data);
 253 xmlNode *expand_idref(xmlNode * input, xmlNode * top);
 254 
 255 void freeXpathObject(xmlXPathObjectPtr xpathObj);
 256 xmlNode *getXpathResult(xmlXPathObjectPtr xpathObj, int index);
 257 void dedupXpathResults(xmlXPathObjectPtr xpathObj);
 258 
 259 static inline int numXpathResults(xmlXPathObjectPtr xpathObj)
     /* [previous][next][first][last][top][bottom][index][help] */
 260 {
 261     if(xpathObj == NULL || xpathObj->nodesetval == NULL) {
 262         return 0;
 263     }
 264     return xpathObj->nodesetval->nodeNr;
 265 }
 266 
 267 bool xml_tracking_changes(xmlNode * xml);
 268 bool xml_document_dirty(xmlNode *xml);
 269 void xml_track_changes(xmlNode * xml, const char *user, xmlNode *acl_source, bool enforce_acls);
 270 void xml_calculate_changes(xmlNode *old_xml, xmlNode *new_xml);
 271 void xml_calculate_significant_changes(xmlNode *old_xml, xmlNode *new_xml);
 272 void xml_accept_changes(xmlNode * xml);
 273 void xml_log_changes(uint8_t level, const char *function, xmlNode *xml);
 274 void xml_log_patchset(uint8_t level, const char *function, xmlNode *xml);
 275 bool xml_patch_versions(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(xmlNode * xml, const char *desc, const char *filename);
 284 char *xml_get_path(xmlNode *xml);
 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, ...)
 289     __attribute__ ((__format__ (__printf__, 2, 3)));
 290 
 291 /*!
 292  * \brief xmlNode destructor which can be used in glib collections
 293  */
 294 void crm_destroy_xml(gpointer data);
 295 
 296 #ifndef PCMK__NO_COMPAT
 297 /* Everything here is deprecated and kept only for public API backward
 298  * compatibility. It will be moved to compatibility.h in a future release.
 299  */
 300 
 301 xmlNode *find_entity(xmlNode *parent, const char *node_name, const char *id);
 302 
 303 gboolean apply_xml_diff(xmlNode *old_xml, xmlNode *diff, xmlNode **new_xml);
 304 
 305 #endif
 306 
 307 #ifdef __cplusplus
 308 }
 309 #endif
 310 
 311 #endif

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