~ubuntu-branches/ubuntu/utopic/pacemaker/utopic-proposed

« back to all changes in this revision

Viewing changes to cib/cibpipe.c

  • Committer: Package Import Robot
  • Author(s): Andres Rodriguez
  • Date: 2013-07-16 16:40:24 UTC
  • mfrom: (1.1.11) (2.2.3 experimental)
  • Revision ID: package-import@ubuntu.com-20130716164024-lvwrf4xivk1wdr3c
Tags: 1.1.9+git20130321-1ubuntu1
* Resync from debian expiremental.
* debian/control:
  - Use lower version for Build-Depends on libcorosync-dev
    and libqb-dev.
  - Build-Depends on libcfg-dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
2
 
 * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
3
 
 * 
4
 
 * This program is free software; you can redistribute it and/or
5
 
 * modify it under the terms of the GNU General Public
6
 
 * License as published by the Free Software Foundation; either
7
 
 * version 2 of the License, or (at your option) any later version.
8
 
 * 
9
 
 * This software is distributed in the hope that it will be useful,
10
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 
 * General Public License for more details.
13
 
 * 
14
 
 * You should have received a copy of the GNU General Public
15
 
 * License along with this library; if not, write to the Free Software
16
 
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
 
 */
18
 
 
19
 
#include <crm_internal.h>
20
 
 
21
 
#include <sys/param.h>
22
 
#include <stdio.h>
23
 
#include <sys/types.h>
24
 
#include <unistd.h>
25
 
 
26
 
#include <stdlib.h>
27
 
#include <errno.h>
28
 
 
29
 
#include <crm/crm.h>
30
 
#include <crm/cib.h>
31
 
#include <crm/msg_xml.h>
32
 
 
33
 
#include <crm/common/xml.h>
34
 
 
35
 
#include "common.h"
36
 
 
37
 
#ifdef HAVE_GETOPT_H
38
 
#  include <getopt.h>
39
 
#endif
40
 
 
41
 
void usage(const char *cmd, int exit_status);
42
 
 
43
 
struct cib_func_entry {
44
 
    const char *op;
45
 
    gboolean read_only;
46
 
    cib_op_t fn;
47
 
};
48
 
 
49
 
/* *INDENT-OFF* */
50
 
static struct cib_func_entry cib_pipe_ops[] = {
51
 
    {CIB_OP_QUERY,      TRUE,  cib_process_query},
52
 
    {CIB_OP_MODIFY,     FALSE, cib_process_modify},
53
 
    {CIB_OP_APPLY_DIFF, FALSE, cib_process_diff},
54
 
    {CIB_OP_BUMP,       FALSE, cib_process_bump},
55
 
    {CIB_OP_REPLACE,    FALSE, cib_process_replace},
56
 
    {CIB_OP_CREATE,     FALSE, cib_process_create},
57
 
    {CIB_OP_DELETE,     FALSE, cib_process_delete},
58
 
    {CIB_OP_ERASE,      FALSE, cib_process_erase},
59
 
};
60
 
/* *INDENT-ON* */
61
 
 
62
 
#define OPTARGS "V?o:QDUCEX:t:MBfRx:P5S$"
63
 
 
64
 
int
65
 
main(int argc, char **argv)
66
 
{
67
 
    int lpc;
68
 
    int flag;
69
 
    int rc = 0;
70
 
    int argerr = 0;
71
 
    int max_msg_types = DIMOF(cib_pipe_ops);
72
 
 
73
 
    int command_options = 0;
74
 
    gboolean changed = FALSE;
75
 
    gboolean force_flag = FALSE;
76
 
    gboolean dangerous_cmd = FALSE;
77
 
 
78
 
    char *buffer = NULL;
79
 
    const char *section = NULL;
80
 
    const char *input_xml = NULL;
81
 
    const char *input_file = NULL;
82
 
    const char *cib_action = NULL;
83
 
 
84
 
    xmlNode *input = NULL;
85
 
    xmlNode *output = NULL;
86
 
    xmlNode *result_cib = NULL;
87
 
    xmlNode *current_cib = NULL;
88
 
 
89
 
    gboolean query = FALSE;
90
 
    cib_op_t *fn = NULL;
91
 
 
92
 
#ifdef HAVE_GETOPT_H
93
 
    int option_index = 0;
94
 
 
95
 
    static struct option long_options[] = {
96
 
        {CIB_OP_ERASE, 0, 0, 'E'},
97
 
        {CIB_OP_QUERY, 0, 0, 'Q'},
98
 
        {CIB_OP_CREATE, 0, 0, 'C'},
99
 
        {CIB_OP_REPLACE, 0, 0, 'R'},
100
 
        {CIB_OP_UPDATE, 0, 0, 'U'},
101
 
        {CIB_OP_MODIFY, 0, 0, 'M'},
102
 
        {"patch", 0, 0, 'P'},
103
 
        {CIB_OP_DELETE, 0, 0, 'D'},
104
 
        {CIB_OP_BUMP, 0, 0, 'B'},
105
 
        {"md5-sum", 0, 0, '5'},
106
 
 
107
 
        {"force", 0, 0, 'f'},
108
 
        {"xml-file", 1, 0, 'x'},
109
 
        {"xml-text", 1, 0, 'X'},
110
 
        {"xml-save", 1, 0, 'S'},
111
 
        {"obj_type", 1, 0, 'o'},
112
 
 
113
 
        {"version", 0, 0, '$'},
114
 
        {"verbose", 0, 0, 'V'},
115
 
        {"help", 0, 0, '?'},
116
 
 
117
 
        {0, 0, 0, 0}
118
 
    };
119
 
#endif
120
 
 
121
 
    crm_log_init_quiet(NULL, LOG_ERR, FALSE, FALSE, argc, argv);
122
 
 
123
 
    while (1) {
124
 
#ifdef HAVE_GETOPT_H
125
 
        flag = getopt_long(argc, argv, OPTARGS, long_options, &option_index);
126
 
#else
127
 
        flag = getopt(argc, argv, OPTARGS);
128
 
#endif
129
 
        if (flag == -1)
130
 
            break;
131
 
 
132
 
        switch (flag) {
133
 
            case 'E':
134
 
                cib_action = CIB_OP_ERASE;
135
 
                dangerous_cmd = TRUE;
136
 
                break;
137
 
            case 'Q':
138
 
                cib_action = CIB_OP_QUERY;
139
 
                break;
140
 
            case 'P':
141
 
                cib_action = CIB_OP_APPLY_DIFF;
142
 
                break;
143
 
            case 'S':
144
 
                cib_action = CIB_OP_SYNC;
145
 
                break;
146
 
            case 'U':
147
 
            case 'M':
148
 
                cib_action = CIB_OP_MODIFY;
149
 
                break;
150
 
            case 'R':
151
 
                cib_action = CIB_OP_REPLACE;
152
 
                break;
153
 
            case 'C':
154
 
                cib_action = CIB_OP_CREATE;
155
 
                break;
156
 
            case 'D':
157
 
                cib_action = CIB_OP_DELETE;
158
 
                break;
159
 
            case '5':
160
 
                cib_action = "md5-sum";
161
 
                break;
162
 
            case 'd':
163
 
                cib_action = CIB_OP_DELETE_ALT;
164
 
                break;
165
 
            case 'm':
166
 
                cib_action = CIB_OP_ISMASTER;
167
 
                command_options |= cib_scope_local;
168
 
                break;
169
 
            case 'B':
170
 
                cib_action = CIB_OP_BUMP;
171
 
                break;
172
 
            case 'o':
173
 
                crm_trace("Option %c => %s", flag, optarg);
174
 
                section = crm_strdup(optarg);
175
 
                break;
176
 
            case 'x':
177
 
                crm_trace("Option %c => %s", flag, optarg);
178
 
                input_file = crm_strdup(optarg);
179
 
                break;
180
 
            case 'X':
181
 
                crm_trace("Option %c => %s", flag, optarg);
182
 
                input_xml = crm_strdup(optarg);
183
 
                break;
184
 
            case 'f':
185
 
                force_flag = TRUE;
186
 
                command_options |= cib_quorum_override;
187
 
                break;
188
 
            case 'V':
189
 
                crm_bump_log_level();
190
 
                break;
191
 
            case '?':          /* Help message */
192
 
                usage(crm_system_name, LSB_EXIT_OK);
193
 
                break;
194
 
            case '$':          /* Version message */
195
 
                crm_help(flag, LSB_EXIT_OK);
196
 
                break;
197
 
            default:
198
 
                ++argerr;
199
 
                break;
200
 
        }
201
 
    }
202
 
 
203
 
    if (cib_action == NULL) {
204
 
        ++argerr;
205
 
    }
206
 
 
207
 
    if (optind > argc) {
208
 
        ++argerr;
209
 
    }
210
 
 
211
 
    if (argerr) {
212
 
        usage(crm_system_name, LSB_EXIT_GENERIC);
213
 
    }
214
 
 
215
 
    if (dangerous_cmd && force_flag == FALSE) {
216
 
        fprintf(stderr, "The supplied command is considered dangerous."
217
 
                "  To prevent accidental destruction of the cluster,"
218
 
                " the --force flag is required in order to proceed.\n");
219
 
        fflush(stderr);
220
 
        usage(crm_system_name, LSB_EXIT_GENERIC);
221
 
    }
222
 
 
223
 
    if (input_file != NULL) {
224
 
        input = filename2xml(input_file);
225
 
        if (input == NULL) {
226
 
            fprintf(stderr, "Couldn't parse input file: %s\n", input_file);
227
 
            return 1;
228
 
        }
229
 
 
230
 
    } else if (input_xml != NULL) {
231
 
        input = string2xml(input_xml);
232
 
        if (input == NULL) {
233
 
            fprintf(stderr, "Couldn't parse input string: %s\n", input_xml);
234
 
            return 1;
235
 
        }
236
 
    }
237
 
 
238
 
    if (input && safe_str_eq(cib_action, CIB_OP_QUERY)) {
239
 
        current_cib = copy_xml(input);
240
 
 
241
 
    } else {
242
 
        current_cib = stdin2xml();
243
 
        if (current_cib == NULL && safe_str_neq(cib_action, CIB_OP_ERASE)) {
244
 
            fprintf(stderr, "Couldn't parse existing CIB from STDIN.\n");
245
 
            return 1;
246
 
        }
247
 
    }
248
 
 
249
 
    if (current_cib == NULL) {
250
 
        current_cib = createEmptyCib();
251
 
    }
252
 
    result_cib = copy_xml(current_cib);
253
 
 
254
 
    if (safe_str_eq(cib_action, "md5-sum")) {
255
 
        char *digest = NULL;
256
 
 
257
 
        digest = calculate_on_disk_digest(current_cib);
258
 
        fprintf(stdout, "%s\n", crm_str(digest));
259
 
        crm_free(digest);
260
 
        return 0;
261
 
    }
262
 
 
263
 
    /* read local config file */
264
 
    if (cib_action == NULL) {
265
 
        crm_err("No operation specified");
266
 
        return cib_operation;
267
 
    }
268
 
 
269
 
    for (lpc = 0; lpc < max_msg_types; lpc++) {
270
 
        if (safe_str_eq(cib_action, cib_pipe_ops[lpc].op)) {
271
 
            fn = &(cib_pipe_ops[lpc].fn);
272
 
            query = cib_pipe_ops[lpc].read_only;
273
 
            break;
274
 
        }
275
 
    }
276
 
 
277
 
    if (fn == NULL) {
278
 
        rc = cib_NOTSUPPORTED;
279
 
    } else {
280
 
        rc = cib_perform_op(cib_action, command_options, fn, query,
281
 
                            section, NULL, input, TRUE, &changed,
282
 
                            current_cib, &result_cib, NULL, &output);
283
 
    }
284
 
 
285
 
    if (rc != cib_ok) {
286
 
        fprintf(stderr, "Call failed: %s\n", cib_error2string(rc));
287
 
        fprintf(stdout, "%c", 0);
288
 
        return -rc;
289
 
    }
290
 
 
291
 
    crm_log_args(argc, argv);
292
 
 
293
 
    if (output) {
294
 
        buffer = dump_xml_formatted(output);
295
 
    } else {
296
 
        buffer = dump_xml_formatted(result_cib);
297
 
    }
298
 
 
299
 
    fprintf(stdout, "%s\n", buffer);
300
 
    fflush(stdout);
301
 
 
302
 
    crm_info("Done");
303
 
    return 0;
304
 
}
305
 
 
306
 
void
307
 
usage(const char *cmd, int exit_status)
308
 
{
309
 
    FILE *stream;
310
 
 
311
 
    stream = exit_status ? stderr : stdout;
312
 
 
313
 
    fprintf(stream, "usage: %s -Q -(x|X)\n", cmd);
314
 
    fprintf(stream, "usage: %s -Q -(x|X) | %s [-%s] | %s [-%s] | ...\n",
315
 
            cmd, cmd, OPTARGS, cmd, OPTARGS);
316
 
    fprintf(stream, "usage: cibadmin -Q  | %s [-%s] | %s [-%s] | ...\n",
317
 
            cmd, OPTARGS, cmd, OPTARGS);
318
 
 
319
 
    fprintf(stream, "\nOptions\n");
320
 
    fprintf(stream, "\t--%s (-%c) <type>\tobject type being operated on\n", "obj_type", 'o');
321
 
    fprintf(stream, "\t\tValid values are:" " nodes, resources, constraints, crm_config, status\n");
322
 
    fprintf(stream, "\t--%s (-%c)\tturn on debug info."
323
 
            "  additional instance increase verbosity\n", "verbose", 'V');
324
 
    fprintf(stream, "\t--%s (-%c)\tthis help message\n", "help", '?');
325
 
 
326
 
    fprintf(stream, "\nCommands\n");
327
 
    fprintf(stream, "\t--%s (-%c)\tErase the contents of the whole CIB\n", CIB_OP_ERASE, 'E');
328
 
    fprintf(stream, "\t--%s (-%c)\t\n", CIB_OP_QUERY, 'Q');
329
 
    fprintf(stream, "\t--%s (-%c)\tCreate an object that does not yet exist\n", CIB_OP_CREATE, 'C');
330
 
    fprintf(stream, "\t--%s (-%c)\tRecursivly update an object in the CIB\n", CIB_OP_UPDATE, 'U');
331
 
    fprintf(stream,
332
 
            "\t--%s (-%c)\tFind the object somewhere in the CIB's XML tree and update it as --"
333
 
            CIB_OP_UPDATE " would\n", CIB_OP_MODIFY, 'M');
334
 
    fprintf(stream, "\t--%s (-%c)\tRecursivly replace an object in the CIB\n", CIB_OP_REPLACE, 'R');
335
 
    fprintf(stream, "\t--%s (-%c)\t\n", CIB_OP_DELETE, 'D');
336
 
    fprintf(stream, "\t\t\tDelete the first object matching the supplied criteria\n");
337
 
    fprintf(stream, "\t\t\tEg. <op id=\"rsc1_op1\" name=\"monitor\"/>\n");
338
 
    fprintf(stream,
339
 
            "\t\t\tThe tagname and all attributes must match in order for the element to be deleted\n");
340
 
 
341
 
    fprintf(stream, "\t--%s (-%c)\t\n", CIB_OP_BUMP, 'B');
342
 
    fprintf(stream, "\t--%s (-%c)\t\tCalculate the configuration's digest.\n", "md5-sum", '5');
343
 
    fprintf(stream, "\nXML data\n");
344
 
    fprintf(stream, "\t--%s (-%c) <filename>\tRetrieve XML from the named file\n", "xml-file", 'x');
345
 
    fprintf(stream, "\t--%s (-%c) <string>\tRetrieve XML from the supplied string\n",
346
 
            "xml-text", 'X');
347
 
    fprintf(stream, "\t--%s (-%c) <filename>\tSave the XML output to the named file\n",
348
 
            "xml-save", 'S');
349
 
    fprintf(stream, "\nNOTE: The current CIB is assumed to be passed in via stdin,"
350
 
            " unless -Q is used in which case -x or -X are also acceptable\n");
351
 
    fflush(stream);
352
 
 
353
 
    exit(exit_status);
354
 
}