This source file includes following definitions.
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <crm_internal.h>
21
22 #include <stdio.h>
23 #include <unistd.h>
24 #include <stdlib.h>
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <libgen.h>
28 #include <time.h>
29
30 #include <sys/param.h>
31 #include <sys/types.h>
32
33 #include <crm/crm.h>
34 #include <crm/msg_xml.h>
35 #include <crm/common/xml.h>
36 #include <crm/common/ipc.h>
37 #include <crm/common/util.h>
38 #include <crm/cluster.h>
39
40 #include <crm/cib.h>
41 #include <crm/attrd.h>
42 #include <sys/utsname.h>
43
44 gboolean BE_QUIET = FALSE;
45 char command = 'G';
46
47 const char *dest_uname = NULL;
48 char *dest_node = NULL;
49 char *set_name = NULL;
50 char *attr_id = NULL;
51 char *attr_name = NULL;
52 char *attr_pattern = NULL;
53 const char *type = NULL;
54 const char *rsc_id = NULL;
55 const char *attr_value = NULL;
56 const char *attr_default = NULL;
57 const char *set_type = NULL;
58
59
60 static struct crm_option long_options[] = {
61
62 {"help", 0, 0, '?', "\tThis text"},
63 {"version", 0, 0, '$', "\tVersion information" },
64 {"verbose", 0, 0, 'V', "\tIncrease debug output"},
65 {"quiet", 0, 0, 'q', "\tPrint only the value on stdout\n"},
66
67 {"name", 1, 0, 'n', "Name of the attribute/option to operate on"},
68 {"pattern", 1, 0, 'P', "Pattern matching names of attributes (only with -v/-D and -l reboot)"},
69
70 {"-spacer-", 0, 0, '-', "\nCommands:"},
71 {"query", 0, 0, 'G', "\tQuery the current value of the attribute/option"},
72 {"update", 1, 0, 'v', "Update the value of the attribute/option"},
73 {"delete", 0, 0, 'D', "\tDelete the attribute/option"},
74
75 {"-spacer-", 0, 0, '-', "\nAdditional Options:"},
76 {"node", 1, 0, 'N', "Set an attribute for the named node (instead of a cluster option). See also: -l"},
77 {"type", 1, 0, 't', "Which part of the configuration to update/delete/query the option in"},
78 {"-spacer-", 0, 0, '-', "\t\t\tValid values: crm_config, rsc_defaults, op_defaults, tickets"},
79 {"lifetime", 1, 0, 'l', "Lifetime of the node attribute"},
80 {"-spacer-", 0, 0, '-', "\t\t\tValid values: reboot, forever"},
81 {"utilization", 0, 0, 'z', "Set an utilization attribute for the node."},
82 {"set-name", 1, 0, 's', "(Advanced) The attribute set in which to place the value"},
83 {"id", 1, 0, 'i', "\t(Advanced) The ID used to identify the attribute"},
84 {"default", 1, 0, 'd', "(Advanced) The default value to display if none is found in the configuration"},
85
86 {"inhibit-policy-engine", 0, 0, '!', NULL, 1},
87
88
89 {"quiet", 0, 0, 'Q', NULL, 1},
90 {"node-uname", 1, 0, 'U', NULL, 1},
91 {"node-uuid", 1, 0, 'u', NULL, 1},
92 {"get-value", 0, 0, 'G', NULL, 1},
93 {"delete-attr", 0, 0, 'D', NULL, 1},
94 {"attr-value", 1, 0, 'v', NULL, 1},
95 {"attr-name", 1, 0, 'n', NULL, 1},
96 {"attr-id", 1, 0, 'i', NULL, 1},
97
98 {"-spacer-", 1, 0, '-', "\nExamples:", pcmk_option_paragraph},
99 {"-spacer-", 1, 0, '-', "Add a new node attribute called 'location' with the value of 'office' for host 'myhost':", pcmk_option_paragraph},
100 {"-spacer-", 1, 0, '-', " crm_attribute --node myhost --name location --update office", pcmk_option_example},
101 {"-spacer-", 1, 0, '-', "Query the value of the 'location' node attribute for host 'myhost':", pcmk_option_paragraph},
102 {"-spacer-", 1, 0, '-', " crm_attribute --node myhost --name location --query", pcmk_option_example},
103 {"-spacer-", 1, 0, '-', "Change the value of the 'location' node attribute for host 'myhost':", pcmk_option_paragraph},
104 {"-spacer-", 1, 0, '-', " crm_attribute --node myhost --name location --update backoffice", pcmk_option_example},
105 {"-spacer-", 1, 0, '-', "Delete the 'location' node attribute for host 'myhost':", pcmk_option_paragraph},
106 {"-spacer-", 1, 0, '-', " crm_attribute --node myhost --name location --delete", pcmk_option_example},
107 {"-spacer-", 1, 0, '-', "Query the value of the cluster-delay cluster option:", pcmk_option_paragraph},
108 {"-spacer-", 1, 0, '-', " crm_attribute --type crm_config --name cluster-delay --query", pcmk_option_example},
109 {"-spacer-", 1, 0, '-', "Query the value of the cluster-delay cluster option. Only print the value:", pcmk_option_paragraph},
110 {"-spacer-", 1, 0, '-', " crm_attribute --type crm_config --name cluster-delay --query --quiet", pcmk_option_example},
111
112 {0, 0, 0, 0}
113 };
114
115
116 int
117 main(int argc, char **argv)
118 {
119 cib_t *the_cib = NULL;
120 int rc = pcmk_ok;
121
122 int cib_opts = cib_sync_call;
123 int argerr = 0;
124 int flag;
125
126 int option_index = 0;
127 int is_remote_node = 0;
128
129 crm_log_cli_init("crm_attribute");
130 crm_set_options(NULL, "<command> -n <attribute> [options]", long_options,
131 "Manage node's attributes and cluster options."
132 "\n\nAllows node attributes and cluster options to be queried, modified and deleted.\n");
133
134 if (argc < 2) {
135 crm_help('?', EX_USAGE);
136 }
137
138 while (1) {
139 flag = crm_get_option(argc, argv, &option_index);
140 if (flag == -1)
141 break;
142
143 switch (flag) {
144 case 'V':
145 crm_bump_log_level(argc, argv);
146 break;
147 case '$':
148 case '?':
149 crm_help(flag, EX_OK);
150 break;
151 case 'G':
152 command = flag;
153 attr_value = optarg;
154 break;
155 case 'D':
156 case 'v':
157 command = flag;
158 attr_value = optarg;
159 crm_log_args(argc, argv);
160 break;
161 case 'q':
162 case 'Q':
163 BE_QUIET = TRUE;
164 break;
165 case 'U':
166 case 'N':
167 dest_uname = strdup(optarg);
168 break;
169 case 'u':
170 dest_node = strdup(optarg);
171 break;
172 case 's':
173 set_name = strdup(optarg);
174 break;
175 case 'l':
176 case 't':
177 type = optarg;
178 break;
179 case 'z':
180 type = XML_CIB_TAG_NODES;
181 set_type = XML_TAG_UTILIZATION;
182 break;
183 case 'n':
184 attr_name = strdup(optarg);
185 break;
186 case 'P':
187 attr_pattern = strdup(optarg);
188 break;
189 case 'i':
190 attr_id = strdup(optarg);
191 break;
192 case 'r':
193 rsc_id = optarg;
194 break;
195 case 'd':
196 attr_default = optarg;
197 break;
198 case '!':
199 crm_warn("Inhibiting notifications for this update");
200 cib_opts |= cib_inhibit_notify;
201 break;
202 default:
203 printf("Argument code 0%o (%c) is not (?yet?) supported\n", flag, flag);
204 ++argerr;
205 break;
206 }
207 }
208
209 if (optind < argc) {
210 printf("non-option ARGV-elements: ");
211 while (optind < argc)
212 printf("%s ", argv[optind++]);
213 printf("\n");
214 }
215
216 if (optind > argc) {
217 ++argerr;
218 }
219
220 if (argerr) {
221 crm_help('?', EX_USAGE);
222 }
223
224 the_cib = cib_new();
225 rc = the_cib->cmds->signon(the_cib, crm_system_name, cib_command);
226
227 if (rc != pcmk_ok) {
228 fprintf(stderr, "Error signing on to the CIB service: %s\n", pcmk_strerror(rc));
229 return crm_exit(rc);
230 }
231
232 if (type == NULL && dest_uname != NULL) {
233 type = "forever";
234 }
235
236 if (safe_str_eq(type, "reboot")) {
237 type = XML_CIB_TAG_STATUS;
238
239 } else if (safe_str_eq(type, "forever")) {
240 type = XML_CIB_TAG_NODES;
241 }
242
243 if (type == NULL && dest_uname == NULL) {
244
245 type = XML_CIB_TAG_CRMCONFIG;
246
247 } else if (safe_str_eq(type, XML_CIB_TAG_CRMCONFIG)) {
248 } else if (safe_str_neq(type, XML_CIB_TAG_TICKETS)) {
249
250
251
252
253 dest_uname = attrd_get_target(dest_uname);
254 if (dest_uname == NULL) {
255 dest_uname = get_local_node_name();
256 }
257
258 rc = query_node_uuid(the_cib, dest_uname, &dest_node, &is_remote_node);
259 if (pcmk_ok != rc) {
260 fprintf(stderr, "Could not map name=%s to a UUID\n", dest_uname);
261 the_cib->cmds->signoff(the_cib);
262 cib_delete(the_cib);
263 return crm_exit(rc);
264 }
265 }
266
267 if ((command == 'D') && (attr_name == NULL) && (attr_pattern == NULL)) {
268 fprintf(stderr, "Error: must specify attribute name or pattern to delete\n");
269 return crm_exit(1);
270 }
271
272 if (attr_pattern) {
273 if (((command != 'v') && (command != 'D'))
274 || safe_str_neq(type, XML_CIB_TAG_STATUS)) {
275
276 fprintf(stderr, "Error: pattern can only be used with till-reboot update or delete\n");
277 return crm_exit(1);
278 }
279 command = 'u';
280 free(attr_name);
281 attr_name = attr_pattern;
282 }
283
284 if (((command == 'v') || (command == 'D') || (command == 'u'))
285 && safe_str_eq(type, XML_CIB_TAG_STATUS)
286 && pcmk_ok == attrd_update_delegate(NULL, command, dest_uname, attr_name,
287 attr_value, type, set_name, NULL, NULL,
288 is_remote_node?attrd_opt_remote:attrd_opt_none)) {
289 crm_info("Update %s=%s sent via attrd", attr_name, command == 'D' ? "<none>" : attr_value);
290
291 } else if (command == 'D') {
292 rc = delete_attr_delegate(the_cib, cib_opts, type, dest_node, set_type, set_name,
293 attr_id, attr_name, attr_value, TRUE, NULL);
294
295 if (rc == -ENXIO) {
296
297
298
299
300 rc = pcmk_ok;
301 }
302
303 } else if (command == 'v') {
304 CRM_LOG_ASSERT(type != NULL);
305 CRM_LOG_ASSERT(attr_name != NULL);
306 CRM_LOG_ASSERT(attr_value != NULL);
307
308 rc = update_attr_delegate(the_cib, cib_opts, type, dest_node, set_type, set_name,
309 attr_id, attr_name, attr_value, TRUE, NULL, is_remote_node ? "remote" : NULL);
310
311 } else {
312
313 char *read_value = NULL;
314
315 rc = read_attr_delegate(the_cib, type, dest_node, set_type, set_name,
316 attr_id, attr_name, &read_value, TRUE, NULL);
317
318 if (rc == -ENXIO && attr_default) {
319 read_value = strdup(attr_default);
320 rc = pcmk_ok;
321 }
322
323 crm_info("Read %s=%s %s%s",
324 attr_name, crm_str(read_value), set_name ? "in " : "", set_name ? set_name : "");
325
326 if (rc == -EINVAL) {
327 rc = pcmk_ok;
328
329 } else if (BE_QUIET == FALSE) {
330 fprintf(stdout, "%s%s %s%s %s%s value=%s\n",
331 type ? "scope=" : "", type ? type : "",
332 attr_id ? "id=" : "", attr_id ? attr_id : "",
333 attr_name ? "name=" : "", attr_name ? attr_name : "",
334 read_value ? read_value : "(null)");
335
336 } else if (read_value != NULL) {
337 fprintf(stdout, "%s\n", read_value);
338 }
339 free(read_value);
340 }
341
342 if (rc == -EINVAL) {
343 printf("Please choose from one of the matches above and supply the 'id' with --attr-id\n");
344
345 } else if (rc != pcmk_ok) {
346 fprintf(stderr, "Error performing operation: %s\n", pcmk_strerror(rc));
347 }
348
349 the_cib->cmds->signoff(the_cib);
350 cib_delete(the_cib);
351 return crm_exit(rc);
352 }