LCOV - code coverage report
Current view: top level - pacemaker - pcmk_verify.c (source / functions) Hit Total Coverage
Test: Pacemaker code coverage Lines: 0 71 0.0 %
Date: 2024-05-07 11:09:47 Functions: 0 3 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2023-2024 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             : #include <crm_internal.h>
      11             : #include <crm/cib/internal.h>
      12             : #include <crm/common/output.h>
      13             : #include <crm/common/results.h>
      14             : #include <crm/common/scheduler.h>
      15             : #include <pacemaker-internal.h>
      16             : #include <pacemaker.h>
      17             : 
      18             : #include <stdint.h>
      19             : #include <sys/types.h>
      20             : #include <sys/stat.h>
      21             : #include <unistd.h>
      22             : 
      23             : #include "libpacemaker_private.h"
      24             : 
      25             : int
      26           0 : pcmk__parse_cib(pcmk__output_t *out, const char *cib_source, xmlNodePtr *cib_object)
      27             : {
      28             :     // @COMPAT Take an enum for cib_source instead of trying to figure it out?
      29           0 :     const char *first = cib_source;
      30             : 
      31           0 :     if (cib_source == NULL) {
      32           0 :         crm_info("Reading XML from: live cluster");
      33           0 :         return cib__signon_query(out, NULL, cib_object);
      34             :     }
      35             : 
      36           0 :     while (isspace(*first)) {
      37           0 :         first++;
      38             :     }
      39             : 
      40           0 :     if (*first == '<') {
      41           0 :         *cib_object = pcmk__xml_parse(cib_source);
      42             :     } else {
      43           0 :         *cib_object = pcmk__xml_read(cib_source);
      44             :     }
      45             : 
      46           0 :     return (*cib_object == NULL)? ENODATA : pcmk_rc_ok;
      47             : }
      48             : 
      49             : int
      50           0 : pcmk__verify(pcmk_scheduler_t *scheduler, pcmk__output_t *out, xmlNode *cib_object)
      51             : {
      52           0 :     int rc = pcmk_rc_ok;
      53           0 :     xmlNode *status = NULL;
      54           0 :     xmlNode *cib_object_copy = NULL;
      55             : 
      56           0 :     if (!pcmk__xe_is(cib_object, PCMK_XE_CIB)) {
      57           0 :         rc = EBADMSG;
      58           0 :         out->err(out, "This tool can only check complete configurations (i.e. those starting with <cib>).");
      59           0 :         goto verify_done;
      60             :     }
      61             : 
      62           0 :     status = pcmk_find_cib_element(cib_object, PCMK_XE_STATUS);
      63           0 :     if (status == NULL) {
      64           0 :         pcmk__xe_create(cib_object, PCMK_XE_STATUS);
      65             :     }
      66             : 
      67           0 :     if (!pcmk__validate_xml(cib_object, NULL,
      68           0 :                             (xmlRelaxNGValidityErrorFunc) out->err, out)) {
      69           0 :         crm_config_error = TRUE;
      70           0 :         rc = pcmk_rc_schema_validation;
      71           0 :         goto verify_done;
      72             : 
      73           0 :     } else if (!pcmk__update_configured_schema(&cib_object, false)) {
      74           0 :         crm_config_error = TRUE;
      75           0 :         out->err(out, "The cluster will NOT be able to use this configuration.\n"
      76             :                  "Please manually update the configuration to conform to the %s syntax.",
      77             :                  pcmk__highest_schema_name());
      78           0 :         rc = pcmk_rc_schema_validation;
      79           0 :         goto verify_done;
      80             :     }
      81             : 
      82             :     /* Process the configuration to set crm_config_error/crm_config_warning.
      83             :      *
      84             :      * @TODO Some parts of the configuration are unpacked only when needed (for
      85             :      * example, action configuration), so we aren't necessarily checking those.
      86             :      */
      87           0 :     if (cib_object != NULL) {
      88           0 :         unsigned long long flags = pcmk_sched_no_counts|pcmk_sched_no_compat;
      89             : 
      90           0 :         if (status == NULL) {
      91             :             // No status available, so do minimal checks
      92           0 :             flags |= pcmk_sched_validate_only;
      93             :         }
      94           0 :         cib_object_copy = pcmk__xml_copy(NULL, cib_object);
      95             : 
      96             :         /* The scheduler takes ownership of the XML object and potentially
      97             :          * frees it later. We want the caller of pcmk__verify to retain
      98             :          * ownership of the passed-in XML object, hence we pass in a copy
      99             :          * to the scheduler.
     100             :          */ 
     101           0 :         pcmk__schedule_actions(cib_object_copy, flags, scheduler);
     102             :     }
     103             : 
     104           0 : verify_done:
     105           0 :     if (crm_config_error) {
     106           0 :         rc = pcmk_rc_schema_validation;
     107           0 :         pcmk__config_err("CIB did not pass schema validation");
     108           0 :     } else if (crm_config_warning) {
     109           0 :         rc = pcmk_rc_schema_validation;
     110             :     }
     111           0 :     return rc;
     112             : }
     113             : 
     114             : int
     115           0 : pcmk_verify(xmlNodePtr *xml, const char *cib_source)
     116             : {
     117           0 :     pcmk_scheduler_t *scheduler = NULL;
     118           0 :     pcmk__output_t *out = NULL;
     119           0 :     int rc = pcmk_rc_ok;
     120             : 
     121           0 :     xmlNode *cib_object = NULL;
     122             : 
     123           0 :     rc = pcmk__xml_output_new(&out, xml);
     124           0 :     if (rc != pcmk_rc_ok) {
     125           0 :         return rc;
     126             :     }
     127             : 
     128           0 :     pe__register_messages(out);
     129           0 :     pcmk__register_lib_messages(out);
     130             : 
     131           0 :     rc = pcmk__parse_cib(out, cib_source, &cib_object);
     132           0 :     if (rc != pcmk_rc_ok) {
     133           0 :         out->err(out, "Couldn't parse input");
     134           0 :         goto done;
     135             :     }
     136             : 
     137           0 :     scheduler = pe_new_working_set();
     138           0 :     if (scheduler == NULL) {
     139           0 :         rc = errno;
     140           0 :         out->err(out, "Couldn't allocate scheduler data: %s", pcmk_rc_str(rc));
     141           0 :         goto done;
     142             :     }
     143             : 
     144           0 :     scheduler->priv = out;
     145           0 :     rc = pcmk__verify(scheduler, out, cib_object);
     146             : 
     147           0 : done:
     148           0 :     pe_free_working_set(scheduler);
     149           0 :     pcmk__xml_output_finish(out, pcmk_rc2exitc(rc), xml);
     150           0 :     free_xml(cib_object);
     151           0 :     return rc;
     152             : }

Generated by: LCOV version 1.14