This source file includes following definitions.
- xml_show_patchset_header
- xml_show_patchset
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- pcmk__register_patchset_messages
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <crm/common/xml.h>
13
14 #include "crmcommon_private.h"
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 static int
41 xml_show_patchset_header(pcmk__output_t *out, const xmlNode *patchset)
42 {
43 int rc = pcmk_rc_no_output;
44 int add[] = { 0, 0, 0 };
45 int del[] = { 0, 0, 0 };
46
47 xml_patch_versions(patchset, add, del);
48
49 if ((add[0] != del[0]) || (add[1] != del[1]) || (add[2] != del[2])) {
50 const char *fmt = crm_element_value(patchset, PCMK_XA_FORMAT);
51 const char *digest = crm_element_value(patchset, PCMK__XA_DIGEST);
52
53 out->info(out, "Diff: --- %d.%d.%d %s", del[0], del[1], del[2], fmt);
54 rc = out->info(out, "Diff: +++ %d.%d.%d %s",
55 add[0], add[1], add[2], digest);
56
57 } else if ((add[0] != 0) || (add[1] != 0) || (add[2] != 0)) {
58 rc = out->info(out, "Local-only Change: %d.%d.%d",
59 add[0], add[1], add[2]);
60 }
61
62 return rc;
63 }
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 static int
80 xml_show_patchset(pcmk__output_t *out, const xmlNode *patchset)
81 {
82 int rc = xml_show_patchset_header(out, patchset);
83 int temp_rc = pcmk_rc_no_output;
84
85 for (const xmlNode *change = pcmk__xe_first_child(patchset, NULL, NULL,
86 NULL);
87 change != NULL; change = pcmk__xe_next(change, NULL)) {
88
89 const char *op = crm_element_value(change, PCMK_XA_OPERATION);
90 const char *xpath = crm_element_value(change, PCMK_XA_PATH);
91
92 if (op == NULL) {
93 continue;
94 }
95
96 if (strcmp(op, PCMK_VALUE_CREATE) == 0) {
97 char *prefix = crm_strdup_printf(PCMK__XML_PREFIX_CREATED " %s: ",
98 xpath);
99
100 temp_rc = pcmk__xml_show(out, prefix, change->children, 0,
101 pcmk__xml_fmt_pretty|pcmk__xml_fmt_open);
102 rc = pcmk__output_select_rc(rc, temp_rc);
103
104
105 for (char *ch = prefix + 2; *ch != '\0'; ch++) {
106 *ch = ' ';
107 }
108
109 temp_rc = pcmk__xml_show(out, prefix, change->children, 0,
110 pcmk__xml_fmt_pretty
111 |pcmk__xml_fmt_children
112 |pcmk__xml_fmt_close);
113 rc = pcmk__output_select_rc(rc, temp_rc);
114 free(prefix);
115
116 } else if (strcmp(op, PCMK_VALUE_MOVE) == 0) {
117 const char *position = crm_element_value(change, PCMK_XE_POSITION);
118
119 temp_rc = out->info(out,
120 PCMK__XML_PREFIX_MOVED " %s moved to offset %s",
121 xpath, position);
122 rc = pcmk__output_select_rc(rc, temp_rc);
123
124 } else if (strcmp(op, PCMK_VALUE_MODIFY) == 0) {
125 xmlNode *clist = pcmk__xe_first_child(change, PCMK_XE_CHANGE_LIST,
126 NULL, NULL);
127 GString *buffer_set = NULL;
128 GString *buffer_unset = NULL;
129
130 for (const xmlNode *child = pcmk__xe_first_child(clist, NULL, NULL,
131 NULL);
132 child != NULL; child = pcmk__xe_next(child, NULL)) {
133
134 const char *name = crm_element_value(child, PCMK_XA_NAME);
135
136 op = crm_element_value(child, PCMK_XA_OPERATION);
137 if (op == NULL) {
138 continue;
139 }
140
141 if (strcmp(op, "set") == 0) {
142 const char *value = crm_element_value(child, PCMK_XA_VALUE);
143
144 pcmk__add_separated_word(&buffer_set, 256, "@", ", ");
145 pcmk__g_strcat(buffer_set, name, "=", value, NULL);
146
147 } else if (strcmp(op, "unset") == 0) {
148 pcmk__add_separated_word(&buffer_unset, 256, "@", ", ");
149 g_string_append(buffer_unset, name);
150 }
151 }
152
153 if (buffer_set != NULL) {
154 temp_rc = out->info(out, "+ %s: %s", xpath, buffer_set->str);
155 rc = pcmk__output_select_rc(rc, temp_rc);
156 g_string_free(buffer_set, TRUE);
157 }
158
159 if (buffer_unset != NULL) {
160 temp_rc = out->info(out, "-- %s: %s",
161 xpath, buffer_unset->str);
162 rc = pcmk__output_select_rc(rc, temp_rc);
163 g_string_free(buffer_unset, TRUE);
164 }
165
166 } else if (strcmp(op, PCMK_VALUE_DELETE) == 0) {
167 int position = -1;
168
169 crm_element_value_int(change, PCMK_XE_POSITION, &position);
170 if (position >= 0) {
171 temp_rc = out->info(out, "-- %s (%d)", xpath, position);
172 } else {
173 temp_rc = out->info(out, "-- %s", xpath);
174 }
175 rc = pcmk__output_select_rc(rc, temp_rc);
176 }
177 }
178
179 return rc;
180 }
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197 PCMK__OUTPUT_ARGS("xml-patchset", "const xmlNode *")
198 static int
199 xml_patchset_default(pcmk__output_t *out, va_list args)
200 {
201 const xmlNode *patchset = va_arg(args, const xmlNode *);
202
203 int format = 1;
204
205 if (patchset == NULL) {
206 crm_trace("Empty patch");
207 return pcmk_rc_no_output;
208 }
209
210 crm_element_value_int(patchset, PCMK_XA_FORMAT, &format);
211 if (format != 2) {
212 crm_err("Unknown patch format: %d", format);
213 return pcmk_rc_bad_xml_patch;
214 }
215
216 return xml_show_patchset(out, patchset);
217 }
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234 PCMK__OUTPUT_ARGS("xml-patchset", "const xmlNode *")
235 static int
236 xml_patchset_log(pcmk__output_t *out, va_list args)
237 {
238 static struct qb_log_callsite *patchset_cs = NULL;
239
240 const xmlNode *patchset = va_arg(args, const xmlNode *);
241
242 uint8_t log_level = pcmk__output_get_log_level(out);
243 int format = 1;
244
245 if (log_level == LOG_NEVER) {
246 return pcmk_rc_no_output;
247 }
248
249 if (patchset == NULL) {
250 crm_trace("Empty patch");
251 return pcmk_rc_no_output;
252 }
253
254 if (patchset_cs == NULL) {
255 patchset_cs = qb_log_callsite_get(__func__, __FILE__, "xml-patchset",
256 log_level, __LINE__,
257 crm_trace_nonlog);
258 }
259
260 if (!crm_is_callsite_active(patchset_cs, log_level, crm_trace_nonlog)) {
261
262 return pcmk_rc_no_output;
263 }
264
265 crm_element_value_int(patchset, PCMK_XA_FORMAT, &format);
266 if (format != 2) {
267 crm_err("Unknown patch format: %d", format);
268 return pcmk_rc_bad_xml_patch;
269 }
270
271 return xml_show_patchset(out, patchset);
272 }
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289 PCMK__OUTPUT_ARGS("xml-patchset", "const xmlNode *")
290 static int
291 xml_patchset_xml(pcmk__output_t *out, va_list args)
292 {
293 const xmlNode *patchset = va_arg(args, const xmlNode *);
294
295 if (patchset != NULL) {
296 GString *buf = g_string_sized_new(1024);
297
298 pcmk__xml_string(patchset, pcmk__xml_fmt_pretty|pcmk__xml_fmt_text, buf,
299 0);
300
301 out->output_xml(out, PCMK_XE_XML_PATCHSET, buf->str);
302 g_string_free(buf, TRUE);
303 return pcmk_rc_ok;
304 }
305 crm_trace("Empty patch");
306 return pcmk_rc_no_output;
307 }
308
309 static pcmk__message_entry_t fmt_functions[] = {
310 { "xml-patchset", "default", xml_patchset_default },
311 { "xml-patchset", "log", xml_patchset_log },
312 { "xml-patchset", "xml", xml_patchset_xml },
313
314 { NULL, NULL, NULL }
315 };
316
317
318
319
320
321
322
323 void
324 pcmk__register_patchset_messages(pcmk__output_t *out) {
325 pcmk__register_messages(out, fmt_functions);
326 }