Skip to content

Feature: tools: Use formatted output in crm_diff.c #3909

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 32 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
9936127
Refactor: tools: Drop forward declarations in crm_diff.c
nrwahl2 Mar 17, 2025
e2cb3e4
Doc: tools: Document input source precedence in crm_diff help output
nrwahl2 Mar 17, 2025
ba537cb
Refactor: tools: Drop xml_file_new arg of crm_diff.c:generate_patch()
nrwahl2 Jun 25, 2025
e02acdb
Refactor: tools: Overhaul input option storage in crm_diff.c
nrwahl2 Mar 17, 2025
aa0f968
Refactor: tools: Use source/target consistently in crm_diff.c
nrwahl2 Mar 17, 2025
8d9aa67
Refactor: various: Drop crm_copy_xml_element() internally
nrwahl2 Mar 17, 2025
1fbf269
API: libcrmcommon: Deprecate crm_copy_xml_element()
nrwahl2 Mar 17, 2025
3591f40
Refactor: tools: Best practices in crm_diff.c:generate_patch()
nrwahl2 Mar 17, 2025
8f208c7
Refactor: libcrmcommon: NULL-check XML private data in display functions
nrwahl2 Mar 17, 2025
c2fe4c3
API: libcrmcommon: xml_apply_patchset() patchset argument is now const
nrwahl2 Mar 17, 2025
83460fe
Refactor: libcrmcommon: Make vfields file-scope in patchset.c
nrwahl2 Mar 17, 2025
1439e9f
Refactor: libcrmcommon: Some best practices in xml_patch_version_check()
nrwahl2 Mar 17, 2025
3d0633e
Refactor: libcrmcommon: Rename lpc to i in xml_patch_version_check()
nrwahl2 Mar 17, 2025
ce9842f
Refactor: libcrmcommon: Clarify check_patchset_versions()
nrwahl2 Mar 18, 2025
db7f615
Refactor: libcrmcommon: Null-check digest in pcmk__digest_xml()
nrwahl2 Jun 25, 2025
283a4c1
Refactor: tools: Clean up crm_diff.c:apply_patch()
nrwahl2 Mar 18, 2025
40b4acb
Refactor: tools: Drop crm_diff.c:apply_patchset()
nrwahl2 Mar 18, 2025
2f46983
Refactor: tools: Drop log_patchset_cib_versions()
nrwahl2 Mar 18, 2025
2ebf936
Doc: tools: Doxygen for crm_diff.c:print_patch()
nrwahl2 Mar 18, 2025
dfc1f8f
Refactor: tools: Clean up crm_diff.c includes
nrwahl2 Mar 18, 2025
85c772e
Low: tools: Be stricter about crm_diff --cib/--no-version
nrwahl2 Mar 18, 2025
f6781fc
Log: tools: Improve error handling in crm_diff.c
nrwahl2 Mar 18, 2025
3f06da9
Refactor: tools: Add pcmk__output_t scaffolding to crm_diff.c
nrwahl2 Mar 18, 2025
2e7edd4
Refactor: tools: Use out->err() in crm_diff, and drop prompts
nrwahl2 Mar 18, 2025
2e32afe
Feature: tools: Deprecate crm_diff --stdin
nrwahl2 Mar 18, 2025
6c5b306
API: libcrmcommon: New PCMK_XE_PATCHSET string constant
nrwahl2 Jun 25, 2025
d36be6c
API: libcrmcommon: New PCMK_XE_UPDATED string constant
nrwahl2 Jun 25, 2025
1e987c9
Test: cts-cli: Avoid Python exception for integer precision
nrwahl2 Jun 26, 2025
5cc0790
Test: cts-cli: crm_diff regression tests
nrwahl2 Jun 26, 2025
eddad0c
Feature: tools: Use formatted output in crm_diff.c
nrwahl2 Mar 18, 2025
0394f59
API: schemas: Add a schema for crm_diff
nrwahl2 Jun 26, 2025
22ae578
Feature: libcrmcommon: Bump feature set to 3.20.2
nrwahl2 Jul 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cts/cli/crm_diff_new.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<cib crm_feature_set="3.2.0" validate-with="pacemaker-3.2" epoch="1" num_updates="0" admin_epoch="0">
<cib crm_feature_set="3.2.0" validate-with="pacemaker-3.2" epoch="1" num_updates="1" admin_epoch="0">
<configuration>
<crm_config>
<cluster_property_set id="cib-bootstrap-options">
Expand Down
63 changes: 63 additions & 0 deletions cts/cli/crm_diff_patchset.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<diff format="2">
<version>
<source admin_epoch="0" epoch="1" num_updates="0"/>
<target admin_epoch="0" epoch="1" num_updates="1"/>
</version>
<change operation="delete" path="/cib/configuration/comment" position="0"/>
<change operation="delete" path="/cib/configuration/comment" position="1"/>
<change operation="delete" path="/cib/configuration/comment" position="2"/>
<change operation="delete" path="/cib/configuration/resources/comment" position="0"/>
<change operation="delete" path="/cib/configuration/resources/primitive[@id='Fencing']/operations/op[@id='Fencing-start-0']"/>
<change operation="modify" path="/cib/configuration/crm_config/cluster_property_set[@id='cib-bootstrap-options']/nvpair[@id='cib-bootstrap-options-cluster-name']">
<change-list>
<change-attr name="value" operation="set" value="mycluster"/>
<change-attr name="name" operation="set" value="cluster-name"/>
</change-list>
<change-result>
<nvpair id="cib-bootstrap-options-cluster-name" value="mycluster" name="cluster-name"/>
</change-result>
</change>
<change operation="create" path="/cib/configuration/nodes" position="4">
<node id="4" uname="node4"/>
</change>
<change operation="create" path="/cib/configuration" position="2">
<!-- test: add a new comment below this one -->
</change>
<change operation="create" path="/cib/configuration" position="3">
<!-- hello world -->
</change>
<change operation="create" path="/cib/configuration/resources" position="0">
<!-- test: modify this comment to say something different -->
</change>
<change operation="modify" path="/cib/configuration/resources/primitive[@id='Fencing']/instance_attributes[@id='Fencing-params']/nvpair[@id='Fencing-pcmk_host_list']">
<change-list>
<change-attr name="value" operation="set" value="node1 node2 node3 node4"/>
</change-list>
<change-result>
<nvpair id="Fencing-pcmk_host_list" name="pcmk_host_list" value="node1 node2 node3 node4"/>
</change-result>
</change>
<change operation="modify" path="/cib/configuration/resources/primitive[@id='Fencing']/operations/op[@id='Fencing-monitor-120s']">
<change-list>
<change-attr name="timeout" operation="set" value="120s"/>
<change-attr name="name" operation="set" value="monitor"/>
</change-list>
<change-result>
<op id="Fencing-monitor-120s" interval="120s" timeout="120s" name="monitor"/>
</change-result>
</change>
<change operation="move" path="/cib/configuration/resources/primitive[@id='dummy']/instance_attributes[@id='dummy-params']/nvpair[@id='dummy-op_sleep']" position="1"/>
<change operation="move" path="/cib/configuration/resources/primitive[@id='dummy']/instance_attributes[@id='dummy-params']/nvpair[@id='dummy-fake']" position="2"/>
<change operation="modify" path="/cib/configuration/resources/primitive[@id='dummy']/operations/op[@id='dummy-monitor-5s']">
<change-list>
<change-attr name="name" operation="set" value="monitor"/>
<change-attr name="timeout" operation="unset"/>
</change-list>
<change-result>
<op id="dummy-monitor-5s" interval="5s" name="monitor"/>
</change-result>
</change>
<change operation="create" path="/cib/configuration" position="6">
<!-- test: move this comment to end of configuration -->
</change>
</diff>
439 changes: 436 additions & 3 deletions cts/cli/regression.crm_diff.exp

Large diffs are not rendered by default.

44 changes: 40 additions & 4 deletions cts/cts-cli.in
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ class Test:

def _log_test_failed(self, app, rc):
"""Log a message when a test fails."""
self._output.append(f"* Failed (rc={rc:.3d}): {app:<23} - {self.desc}")
self._output.append(f"* Failed (rc={rc:03d}): {app:<23} - {self.desc}")

def _log_test_passed(self, app):
"""Log a message when a test passes."""
Expand Down Expand Up @@ -2385,10 +2385,46 @@ class CrmDiffRegressionTest(RegressionTest):
@property
def tests(self):
"""A list of Test instances to be run as part of this regression test."""

old_file = f"{cts_cli_data}/crm_diff_old.xml"
new_file = f"{cts_cli_data}/crm_diff_new.xml"
patch_file = f"{cts_cli_data}/crm_diff_patchset.xml"

with open(f"{cts_cli_data}/crm_diff_old.xml", "r") as file:
old_str = f"'{file.read()}'"
with open(f"{cts_cli_data}/crm_diff_new.xml", "r") as file:
new_str = f"'{file.read()}'"

return [
Test("Create an XML patchset",
f"crm_diff -o {cts_cli_data}/crm_diff_old.xml -n {cts_cli_data}/crm_diff_new.xml",
expected_rc=ExitStatus.ERROR)
Test("Create an XML patchset from files",
f"crm_diff -o {old_file} -n {new_file}",
expected_rc=ExitStatus.ERROR),
Test("Create an XML patchset from strings",
f"crm_diff -O {old_str} -N {new_str}",
expected_rc=ExitStatus.ERROR),
Test("Create an XML patchset from old file, new string",
f"crm_diff -o {old_file} -N {new_str}",
expected_rc=ExitStatus.ERROR),
Test("Create an XML patchset from old string, new file",
f"crm_diff -O {old_str} -n {new_file}",
expected_rc=ExitStatus.ERROR),

Test("Create an XML patchset from files",
f"crm_diff -o {old_file} -n {new_file} --cib",
expected_rc=ExitStatus.ERROR),
Test("Create an XML patchset from files",
f"crm_diff -o {old_file} -n {new_file} --no-version",
expected_rc=ExitStatus.ERROR),
Test("Create an XML patchset from files",
f"crm_diff -o {old_file} -n {new_file} --cib --no-version",
expected_rc=ExitStatus.USAGE),

Test("Apply an XML patchset to a file",
f"crm_diff -o {old_file} -p {patch_file}"),
Test("Apply an XML patchset to a string",
f"crm_diff -O {old_str} -p {patch_file}"),
Test("Apply an XML patchset to a file",
f"crm_diff -o {old_file} -p {patch_file} --cib"),
]


Expand Down
11 changes: 6 additions & 5 deletions daemons/controld/controld_te_actions.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2004-2024 the Pacemaker project contributors
* Copyright 2004-2025 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
Expand Down Expand Up @@ -299,10 +299,11 @@ controld_record_action_event(pcmk__graph_action_t *action,
rsc = pcmk__xe_create(rsc, PCMK__XE_LRM_RESOURCE);
crm_xml_add(rsc, PCMK_XA_ID, rsc_id);


crm_copy_xml_element(action_rsc, rsc, PCMK_XA_TYPE);
crm_copy_xml_element(action_rsc, rsc, PCMK_XA_CLASS);
crm_copy_xml_element(action_rsc, rsc, PCMK_XA_PROVIDER);
crm_xml_add(rsc, PCMK_XA_TYPE, crm_element_value(action_rsc, PCMK_XA_TYPE));
crm_xml_add(rsc, PCMK_XA_CLASS,
crm_element_value(action_rsc, PCMK_XA_CLASS));
crm_xml_add(rsc, PCMK_XA_PROVIDER,
crm_element_value(action_rsc, PCMK_XA_PROVIDER));

pcmk__create_history_xml(rsc, op, CRM_FEATURE_SET, target_rc, target,
__func__);
Expand Down
3 changes: 2 additions & 1 deletion include/crm/common/xml.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ extern "C" {

xmlNode *xml_create_patchset(
int format, xmlNode *source, xmlNode *target, bool *config, bool manage_version);
int xml_apply_patchset(xmlNode *xml, xmlNode *patchset, bool check_version);
int xml_apply_patchset(xmlNode *xml, const xmlNode *patchset,
bool check_version);

#ifdef __cplusplus
}
Expand Down
20 changes: 1 addition & 19 deletions include/crm/common/xml_element.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2004-2024 the Pacemaker project contributors
* Copyright 2004-2025 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
Expand Down Expand Up @@ -42,24 +42,6 @@ int crm_element_value_timeval(const xmlNode *data, const char *name_sec,
const char *name_usec, struct timeval *dest);
char *crm_element_value_copy(const xmlNode *data, const char *name);

/*!
* \brief Copy an element from one XML object to another
*
* \param[in] obj1 Source XML
* \param[in,out] obj2 Destination XML
* \param[in] element Name of element to copy
*
* \return Pointer to copied value (from source)
*/
static inline const char *
crm_copy_xml_element(const xmlNode *obj1, xmlNode *obj2, const char *element)
{
const char *value = crm_element_value(obj1, element);

crm_xml_add(obj2, element, value);
return value;
}

#ifdef __cplusplus
}
#endif
Expand Down
6 changes: 5 additions & 1 deletion include/crm/common/xml_element_compat.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2004-2024 the Pacemaker project contributors
* Copyright 2004-2025 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
Expand Down Expand Up @@ -35,6 +35,10 @@ void crm_xml_set_id(xmlNode *xml, const char *format, ...) G_GNUC_PRINTF(2, 3);
//! \deprecated Do not use
xmlNode *sorted_xml(xmlNode *input, xmlNode *parent, gboolean recursive);

//! \deprecated Do not use
const char *crm_copy_xml_element(const xmlNode *obj1, xmlNode *obj2,
const char *element);

#ifdef __cplusplus
}
#endif
Expand Down
4 changes: 3 additions & 1 deletion include/crm/common/xml_names.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2004-2024 the Pacemaker project contributors
* Copyright 2004-2025 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
Expand Down Expand Up @@ -157,6 +157,7 @@ extern "C" {
#define PCMK_XE_PACEMAKERD "pacemakerd"
#define PCMK_XE_PARAMETER "parameter"
#define PCMK_XE_PARAMETERS "parameters"
#define PCMK_XE_PATCHSET "patchset"
#define PCMK_XE_PERIOD "period"
#define PCMK_XE_PODMAN "podman"
#define PCMK_XE_PORT_MAPPING "port-mapping"
Expand Down Expand Up @@ -214,6 +215,7 @@ extern "C" {
#define PCMK_XE_TIMING "timing"
#define PCMK_XE_TIMINGS "timings"
#define PCMK_XE_TRANSITION "transition"
#define PCMK_XE_UPDATED "updated"
#define PCMK_XE_UTILIZATION "utilization"
#define PCMK_XE_UTILIZATIONS "utilizations"
#define PCMK_XE_VALIDATE "validate"
Expand Down
2 changes: 1 addition & 1 deletion include/crm/crm.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ extern "C" {
* >=3.2.0: DC supports PCMK_EXEC_INVALID and PCMK_EXEC_NOT_CONNECTED
* >=3.19.0: DC supports PCMK__CIB_REQUEST_COMMIT_TRANSACT
*/
#define CRM_FEATURE_SET "3.20.1"
#define CRM_FEATURE_SET "3.20.2"

/* 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
Expand Down
3 changes: 2 additions & 1 deletion include/crm_internal.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2006-2024 the Pacemaker project contributors
* Copyright 2006-2025 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
Expand Down Expand Up @@ -38,6 +38,7 @@

#include <crm/lrmd.h>
#include <crm/cluster/internal.h>
#include <crm/common/cmdline_internal.h>
#include <crm/common/digest_internal.h>
#include <crm/common/logging.h>
#include <crm/common/logging_internal.h>
Expand Down
5 changes: 5 additions & 0 deletions lib/common/digest.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ pcmk__digest_xml(const xmlNode *xml, bool filter)

pcmk__xml_string(xml, (filter? pcmk__xml_fmt_filtered : 0), buf, 0);
digest = crm_md5sum(buf->str);
if (digest == NULL) {
goto done;
}

pcmk__if_tracing(
{
Expand All @@ -192,6 +195,8 @@ pcmk__digest_xml(const xmlNode *xml, bool filter)
},
{}
);

done:
g_string_free(buf, TRUE);
return digest;
}
Expand Down
Loading