root/tools/crm_attribute.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. main

   1 
   2 /*
   3  * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
   4  *
   5  * This program is free software; you can redistribute it and/or
   6  * modify it under the terms of the GNU General Public
   7  * License as published by the Free Software Foundation; either
   8  * version 2 of the License, or (at your option) any later version.
   9  *
  10  * This software is distributed in the hope that it will be useful,
  11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13  * General Public License for more details.
  14  *
  15  * You should have received a copy of the GNU General Public
  16  * License along with this library; if not, write to the Free Software
  17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  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 /* *INDENT-OFF* */
  60 static struct crm_option long_options[] = {
  61     /* Top-level Options */
  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     /* legacy */
  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 /* *INDENT-ON* */
 115 
 116 int
 117 main(int argc, char **argv)
     /* [previous][next][first][last][top][bottom][index][help] */
 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         /* we're updating cluster options - don't populate dest_node */
 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         /* If we are being called from a resource agent via the cluster,
 250          * the correct local node name will be passed as an environment
 251          * variable. Otherwise, we have to ask the cluster.
 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             /* Nothing to delete...
 297              * which means it's not there...
 298              * which is what the admin wanted
 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 {                    /* query */
 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 }

/* [previous][next][first][last][top][bottom][index][help] */