Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:lafenghu
pacemaker
pacemaker-crm_ticket.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File pacemaker-crm_ticket.diff of Package pacemaker
commit 1fc6caa4665dacaee97e314ba3a292cfba873762 Author: Gao,Yan <ygao@suse.com> Date: Fri Mar 23 16:58:00 2012 +0800 High: Tools: Implement a new crm_ticket diff --git a/tools/Makefile.am b/tools/Makefile.am index a2b2a87..2c2192c 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -31,7 +31,7 @@ header_HEADERS = attrd.h pcmkdir = $(datadir)/$(PACKAGE) pcmk_DATA = report.common report.collector -sbin_SCRIPTS = crm_report crm_standby crm_master crm_failcount crm_ticket +sbin_SCRIPTS = crm_report crm_standby crm_master crm_failcount EXTRA_DIST = $(sbin_SCRIPTS) halibdir = $(CRM_DAEMON_DIR) @@ -40,7 +40,7 @@ halib_PROGRAMS = attrd halib_PYTHON = crm_primitive.py hb2openais-helper.py sbin_PROGRAMS = crm_simulate crmadmin cibadmin crm_node crm_attribute crm_resource crm_verify \ - crm_uuid crm_shadow attrd_updater crm_diff crm_mon iso8601 + crm_uuid crm_shadow attrd_updater crm_diff crm_mon iso8601 crm_ticket testdir = $(datadir)/$(PACKAGE)/tests test_SCRIPTS = coverage.sh @@ -124,6 +124,12 @@ attrd_LDADD = $(top_builddir)/lib/cluster/libcrmcluster.la $(COMMONLIBS) attrd_updater_SOURCES = attrd_updater.c attrd_updater_LDADD = $(COMMONLIBS) +crm_ticket_SOURCES = crm_ticket.c +crm_ticket_LDADD = $(top_builddir)/lib/pengine/libpe_rules.la \ + $(top_builddir)/lib/pengine/libpe_status.la \ + $(top_builddir)/pengine/libpengine.la \ + $(COMMONLIBS) + if BUILD_SERVICELOG notifyServicelogEvent_SOURCES = notifyServicelogEvent.c notifyServicelogEvent_CFLAGS = $(SERVICELOG_CFLAGS) diff --git a/tools/crm_ticket b/tools/crm_ticket deleted file mode 100755 index 640a541..0000000 --- a/tools/crm_ticket +++ /dev/null @@ -1,122 +0,0 @@ -#!/bin/bash - -options="" -ticket="" -update_value="" -last_granted="" -delete_attr="false" -force="false" - -TEMP=`getopt -o DGQVThfv:i:t: --long help,version,ticket:,attr-value:,delete-attr,get-value,attr-id:,force,quiet,time \ - -n 'crm_ticket' -- "$@"` - -if [ $? != 0 ] ; then echo "crm_ticket - A convenience wrapper for crm_attribute"; echo ""; crm_attribute -?; exit 1 ; fi - -# Note the quotes around `$TEMP': they are essential! -eval set -- "$TEMP" - -confirm() { - action=$1 - ticket=$2 - - if [ X$action = X"grant" ]; then - warning="The crm_ticket command cannot help you verify if '$ticket' is already granted elsewhere." - word="to" - else - warning="Revoking '$ticket' will trigger the specified 'loss-policy' relating to '$ticket'." - word="from" - fi - - while :; do - printf "$warning\nAre you sure you want to $action '$ticket' $word this site? (y/n)" - read ans - if echo $ans | grep -iqs '^[yn]'; then - echo $ans | grep -iqs '^y' - return $? - else - echo Please answer with y or n - fi - done -} - -while true ; do - case "$1" in - -v|--attr-value) options="$options $1 $2"; update_value=$2; shift; shift;; - -i|--attr-id) options="$options $1 $2"; shift; shift;; - -D|--delete-attr) options="$options $1"; delete_attr="true"; shift;; - -Q|--quiet|-G|--get-value|-V) options="$options $1"; shift;; - -t|--ticket-id) ticket=$2; shift; shift;; - -T|--time) last_granted="time"; shift;; - -f|--force) force="true"; shift;; - --version) crm_attribute --version; exit 0;; - -h|--help) - echo "crm_ticket - A convenience wrapper for crm_attribute"; - echo ""; - echo "Grants or revokes the specified ticket for the cluster"; - echo ""; - echo "Usage: crm_ticket -t ticket_name command [options]"; - echo "Options:" - echo " -h, --help This text" - echo " --version Version information" - echo " -V, --verbose Increase debug output" - echo " -q, --quiet Print only the value on stdout" - echo "" - echo " -t, --ticket-id=value The ticket to update" - echo "" - echo "Commands:" - echo " -G, --query Query if the specified ticket is granted or not" - echo " -v, --update=value Grant/Revoke the specified ticket" - echo " -D, --delete Delete the granting/revoking record" - echo " -T, --time Query the time of last granted the specified ticket" - echo "" - echo "Additional Options:" - echo " -i, --id=value (Advanced) The ID used to identify the attribute" - echo " -f, --force (Advanced) Force the action to be performed" - exit 0;; - --) shift ; break ;; - *) echo "Unknown option: $1. See --help for details." exit 1;; - esac -done - -if [ X$last_granted != X ]; then - options="$options -n last-granted-$ticket -G -d -1" - crm_attribute $options -t tickets - rc=$? - exit $rc -else - options="$options -n granted-ticket-$ticket" -fi - -case "$update_value" in - true|yes|1) - if [ X$force != X"true" ]; then - confirm "grant" $ticket || exit 1 - fi - - crm_attribute $options -t tickets >/dev/null 2>&1 - rc=$? - if [ $rc = 0 ]; then - options="$options -n last-granted-$ticket -v `date +%s`" - crm_attribute $options -t tickets >/dev/null 2>&1 - rc=$? - exit $rc - else - echo "Failed to grant ticket $ticket" - exit $rc - fi - ;; - *) - if [ X$update_value != X -o X$delete_attr = X"true" ]; then - if [ X$force != X"true" ]; then - confirm "revoke" $ticket || exit 1 - fi - crm_attribute $options -t tickets >/dev/null 2>&1 - rc=$? - exit $rc - else - crm_attribute $options -t tickets -d false - rc=$? - exit $rc - fi - ;; -esac diff --git a/tools/crm_ticket.c b/tools/crm_ticket.c new file mode 100644 index 0000000..f90ba23 --- /dev/null +++ b/tools/crm_ticket.c @@ -0,0 +1,964 @@ + +/* + * Copyright (C) 2012 Gao,Yan <ygao@suse.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <crm_internal.h> + +#include <sys/param.h> + +#include <crm/crm.h> + +#include <stdio.h> +#include <sys/types.h> +#include <unistd.h> + +#include <stdlib.h> +#include <errno.h> +#include <fcntl.h> +#include <libgen.h> + +#include <crm/msg_xml.h> +#include <crm/common/xml.h> +#include <crm/common/ipc.h> + +#include <crm/cib.h> +#include <crm/pengine/rules.h> +#include <crm/pengine/status.h> + +gboolean do_force = FALSE; +gboolean BE_QUIET = FALSE; +const char *ticket_id = NULL; +const char *attr_name = "granted"; +const char *attr_value = NULL; +const char *attr_id = NULL; +const char *set_name = NULL; +const char *attr_default = NULL; +char ticket_cmd = 'S'; +char *xml_file = NULL; +int cib_options = cib_sync_call; + +extern void cleanup_alloc_calculations(pe_working_set_t * data_set); + +#define CMD_ERR(fmt, args...) do { \ + crm_warn(fmt, ##args); \ + fprintf(stderr, fmt, ##args); \ + } while(0) + +static ticket_t * +find_ticket(const char *ticket_id , pe_working_set_t * data_set) +{ + ticket_t *ticket = NULL; + ticket = g_hash_table_lookup(data_set->tickets, ticket_id); + + return ticket; +} + +static void +print_date(time_t time) +{ + int lpc = 0; + char date_str[26]; + + asctime_r(localtime(&time), date_str); + for (; lpc < 26; lpc++) { + if (date_str[lpc] == '\n') { + date_str[lpc] = 0; + } + } + fprintf(stdout,"'%s'", date_str); +} + +static int +print_ticket(ticket_t *ticket, gboolean raw, gboolean details) +{ + if (raw) { + fprintf(stdout, "%s\n", ticket->id); + return cib_ok; + } + + fprintf(stdout, "%s\t%s %s", + ticket->id, ticket->granted?"granted":"revoked", + ticket->standby?"[standby]":" "); + + if (details && g_hash_table_size(ticket->state) > 0) { + GHashTableIter iter; + const char *name = NULL; + const char *value = NULL; + int lpc = 0; + + fprintf(stdout, " ("); + + g_hash_table_iter_init(&iter, ticket->state); + while (g_hash_table_iter_next(&iter, (void **)&name, (void **)&value)) { + if (lpc > 0) { + fprintf(stdout, ", "); + } + fprintf(stdout, "%s=", name); + if (crm_str_eq(name, "last-granted", TRUE) + || crm_str_eq(name, "expires", TRUE)) { + print_date(crm_parse_int(value, 0)); + } else { + fprintf(stdout, "%s", value); + } + lpc++; + } + + fprintf(stdout, ")\n"); + + } else { + if (ticket->last_granted > -1) { + fprintf(stdout, " last-granted="); + print_date(ticket->last_granted); + } + fprintf(stdout, "\n"); + } + + return cib_ok; +} + +static int +print_ticket_list(pe_working_set_t * data_set, gboolean raw, gboolean details) +{ + GHashTableIter iter; + ticket_t *ticket = NULL; + + g_hash_table_iter_init(&iter, data_set->tickets); + + while (g_hash_table_iter_next(&iter, NULL, (void **)&ticket)) { + print_ticket(ticket, raw, details); + } + + return cib_ok; +} + +static int +find_ticket_state(cib_t * the_cib, const char * ticket_id, xmlNode ** ticket_state_xml) +{ + int offset = 0; + static int xpath_max = 1024; + enum cib_errors rc = cib_ok; + xmlNode *xml_search = NULL; + + char *xpath_string = NULL; + + CRM_ASSERT(ticket_state_xml != NULL); + *ticket_state_xml = NULL; + + crm_malloc0(xpath_string, xpath_max); + offset += + snprintf(xpath_string + offset, xpath_max - offset, "%s", "/cib/status/tickets"); + + if (ticket_id) { + offset += snprintf(xpath_string + offset, xpath_max - offset, "/%s[@id=\"%s\"]", + XML_CIB_TAG_TICKET_STATE, ticket_id); + } + + rc = the_cib->cmds->query(the_cib, xpath_string, &xml_search, + cib_sync_call | cib_scope_local | cib_xpath); + + if (rc != cib_ok) { + goto bail; + } + + crm_log_xml_debug(xml_search, "Match"); + if (xml_has_children(xml_search)) { + if (ticket_id) { + fprintf(stdout, "Multiple ticket_states match ticket_id=%s\n", ticket_id); + } + *ticket_state_xml = xml_search; + } else { + *ticket_state_xml = xml_search; + } + + bail: + crm_free(xpath_string); + return rc; +} + +static int +find_ticket_constraints(cib_t * the_cib, const char * ticket_id, xmlNode ** ticket_cons_xml) +{ + int offset = 0; + static int xpath_max = 1024; + enum cib_errors rc = cib_ok; + xmlNode *xml_search = NULL; + + char *xpath_string = NULL; + + CRM_ASSERT(ticket_cons_xml != NULL); + *ticket_cons_xml = NULL; + + crm_malloc0(xpath_string, xpath_max); + offset += + snprintf(xpath_string + offset, xpath_max - offset, "%s/%s", + get_object_path(XML_CIB_TAG_CONSTRAINTS), XML_CONS_TAG_RSC_TICKET); + + if (ticket_id) { + offset += snprintf(xpath_string + offset, xpath_max - offset, "[@ticket=\"%s\"]", + ticket_id); + } + + rc = the_cib->cmds->query(the_cib, xpath_string, &xml_search, + cib_sync_call | cib_scope_local | cib_xpath); + + if (rc != cib_ok) { + goto bail; + } + + crm_log_xml_debug(xml_search, "Match"); + *ticket_cons_xml = xml_search; + + bail: + crm_free(xpath_string); + return rc; +} + +static int +dump_ticket_xml(cib_t * the_cib, const char *ticket_id) +{ + enum cib_errors rc = cib_ok; + xmlNode * state_xml = NULL; + + rc = find_ticket_state(the_cib, ticket_id, &state_xml); + + if (state_xml == NULL) { + return rc; + } + + fprintf(stdout, "State XML:\n"); + if (state_xml) { + char *state_xml_str = NULL; + + state_xml_str = dump_xml_formatted(state_xml); + fprintf(stdout, "\n%s\n", crm_str(state_xml_str)); + free_xml(state_xml); + crm_free(state_xml_str); + } + + return cib_ok; +} + +static int +dump_constraints(cib_t * the_cib, const char * ticket_id) +{ + enum cib_errors rc = cib_ok; + xmlNode * cons_xml = NULL; + char *cons_xml_str = NULL; + + rc = find_ticket_constraints(the_cib, ticket_id, &cons_xml); + + if (cons_xml == NULL) { + return rc; + } + + cons_xml_str = dump_xml_formatted(cons_xml); + fprintf(stdout, "Constraints XML:\n\n%s\n", crm_str(cons_xml_str)); + free_xml(cons_xml); + crm_free(cons_xml_str); + + return cib_ok; +} + +static int +find_ticket_state_attr_legacy(cib_t * the_cib, const char *attr, const char *ticket_id, const char *set_type, + const char *set_name, const char *attr_id, const char *attr_name, char **value) +{ + int offset = 0; + static int xpath_max = 1024; + enum cib_errors rc = cib_ok; + xmlNode *xml_search = NULL; + + char *xpath_string = NULL; + + CRM_ASSERT(value != NULL); + *value = NULL; + + crm_malloc0(xpath_string, xpath_max); + offset += + snprintf(xpath_string + offset, xpath_max - offset, "%s", "/cib/status/tickets"); + + if (set_type) { + offset += snprintf(xpath_string + offset, xpath_max - offset, "/%s", set_type); + if (set_name) { + offset += snprintf(xpath_string + offset, xpath_max - offset, "[@id=\"%s\"]", set_name); + } + } + + offset += snprintf(xpath_string + offset, xpath_max - offset, "//nvpair["); + if (attr_id) { + offset += snprintf(xpath_string + offset, xpath_max - offset, "@id=\"%s\"", attr_id); + } + + if (attr_name) { + const char *attr_prefix = NULL; + const char *long_key = NULL; + + if (crm_str_eq(attr_name, "granted", TRUE)) { + attr_prefix = "granted-ticket"; + } else { + attr_prefix = attr_name; + } + long_key = crm_concat(attr_prefix, ticket_id, '-'); + + if (attr_id) { + offset += snprintf(xpath_string + offset, xpath_max - offset, " and "); + } + offset += snprintf(xpath_string + offset, xpath_max - offset, "@name=\"%s\"", long_key); + } + offset += snprintf(xpath_string + offset, xpath_max - offset, "]"); + + rc = the_cib->cmds->query(the_cib, xpath_string, &xml_search, + cib_sync_call | cib_scope_local | cib_xpath); + + if (rc != cib_ok) { + goto bail; + } + + crm_log_xml_debug(xml_search, "Match"); + if (xml_has_children(xml_search)) { + xmlNode *child = NULL; + + rc = cib_missing_data; + fprintf(stdout, "Multiple attributes match name=%s\n", attr_name); + + for (child = __xml_first_child(xml_search); child != NULL; child = __xml_next(child)) { + fprintf(stdout, " Value: %s \t(id=%s)\n", + crm_element_value(child, XML_NVPAIR_ATTR_VALUE), ID(child)); + } + + } else { + const char *tmp = crm_element_value(xml_search, attr); + + if (tmp) { + *value = crm_strdup(tmp); + } + } + + bail: + crm_free(xpath_string); + free_xml(xml_search); + return rc; +} + +static int +delete_ticket_state_attr_legacy(const char *ticket_id, const char *set_name, const char *attr_id, + const char *attr_name, cib_t * cib) +{ + xmlNode *xml_obj = NULL; + + int rc = cib_ok; + char *local_attr_id = NULL; + + rc = find_ticket_state_attr_legacy(cib, XML_ATTR_ID, ticket_id, XML_TAG_ATTR_SETS, set_name, attr_id, attr_name, + &local_attr_id); + + if (rc == cib_NOTEXISTS) { + return cib_ok; + + } else if (rc != cib_ok) { + return rc; + } + + if (attr_id == NULL) { + attr_id = local_attr_id; + } + + xml_obj = create_xml_node(NULL, XML_CIB_TAG_NVPAIR); + crm_xml_add(xml_obj, XML_ATTR_ID, attr_id); + /*crm_xml_add(xml_obj, XML_NVPAIR_ATTR_NAME, attr_name);*/ + + crm_log_xml_debug(xml_obj, "Delete"); + + rc = cib->cmds->delete(cib, XML_CIB_TAG_STATUS, xml_obj, cib_options); + + if (rc == cib_ok) { + fprintf(stdout, "Deleted legacy %s state attribute: id=%s%s%s%s%s\n", ticket_id, local_attr_id, + set_name ? " set=" : "", set_name ? set_name : "", + attr_name ? " name=" : "", attr_name ? attr_name : ""); + } + + free_xml(xml_obj); + crm_free(local_attr_id); + return rc; +} + +static int +get_ticket_state_attr(const char *ticket_id, const char *attr_name, const char **attr_value, pe_working_set_t * data_set) +{ + ticket_t *ticket = NULL; + + CRM_ASSERT(attr_value != NULL); + *attr_value = NULL; + + ticket = g_hash_table_lookup(data_set->tickets, ticket_id); + if (ticket == NULL) { + return cib_NOTEXISTS; + } + + *attr_value = g_hash_table_lookup(ticket->state, attr_name); + if (*attr_value == NULL) { + return cib_NOTEXISTS; + } + + return cib_ok; +} + +static int +delete_ticket_state_attr(const char *ticket_id, const char *attr_name, cib_t * cib) +{ + xmlNode *ticket_state_xml = NULL; + + int rc = cib_ok; + + rc = find_ticket_state(cib, ticket_id, &ticket_state_xml); + + if (rc == cib_NOTEXISTS) { + return cib_ok; + + } else if (rc != cib_ok) { + return rc; + } + + xml_remove_prop(ticket_state_xml, attr_name); + rc = cib->cmds->replace(cib, XML_CIB_TAG_STATUS, ticket_state_xml, cib_options); + + if (rc == cib_ok) { + fprintf(stdout, "Deleted %s state attribute: %s%s\n", ticket_id, + attr_name ? " name=" : "", attr_name ? attr_name : ""); + } + + free_xml(ticket_state_xml); + return rc; +} + +static int +set_ticket_state_attr(const char *ticket_id, const char *attr_name, + const char *attr_value, cib_t * cib) +{ + enum cib_errors rc = cib_ok; + xmlNode *xml_top = NULL; + xmlNode *ticket_state_xml = NULL; + + rc = find_ticket_state(cib, ticket_id, &ticket_state_xml); + if (rc == cib_ok) { + crm_debug("Found a match state for ticket: id=%s", ticket_id); + xml_top = ticket_state_xml; + + } else if (rc != cib_NOTEXISTS) { + return rc; + + } else { + xmlNode *xml_obj = NULL; + + xml_top = create_xml_node(NULL, XML_CIB_TAG_STATUS); + xml_obj = create_xml_node(xml_top, XML_CIB_TAG_TICKETS); + ticket_state_xml = create_xml_node(xml_obj, XML_CIB_TAG_TICKET_STATE); + crm_xml_add(ticket_state_xml, XML_ATTR_ID, ticket_id); + } + + crm_xml_add(ticket_state_xml, attr_name, attr_value); + + crm_log_xml_debug(xml_top, "Update"); + + rc = cib->cmds->modify(cib, XML_CIB_TAG_STATUS, xml_top, cib_options); + + free_xml(xml_top); + + return rc; +} + +static int +delete_ticket_state(const char *ticket_id, cib_t * cib) +{ + xmlNode *ticket_state_xml = NULL; + + enum cib_errors rc = cib_ok; + + rc = find_ticket_state(cib, ticket_id, &ticket_state_xml); + + if (rc == cib_NOTEXISTS) { + return cib_ok; + + } else if (rc != cib_ok) { + return rc; + } + + crm_log_xml_debug(ticket_state_xml, "Delete"); + + rc = cib->cmds->delete(cib, XML_CIB_TAG_STATUS, ticket_state_xml, cib_options); + + if (rc == cib_ok) { + fprintf(stdout, "Cleaned up %s\n", ticket_id); + } + + free_xml(ticket_state_xml); + return rc; +} + +static gboolean +confirm(const char *ticket_id, const char *action) +{ + gboolean rc = FALSE; + int offset = 0; + static int text_max = 1024; + + char *warning = NULL; + const char * word = NULL; + + crm_malloc0(warning, text_max); + if (safe_str_eq(action, "grant")) { + offset += snprintf(warning + offset, text_max - offset, + "The command cannot help you verify if '%s' is already granted elsewhere.\n", + ticket_id); + word = "to"; + + } else { + offset += snprintf(warning + offset, text_max - offset, + "Revoking '%s' can trigger the specified 'loss-policy'(s) relating to '%s'.\n\n", + ticket_id, ticket_id); + + offset += snprintf(warning + offset, text_max - offset, + "You can check that with:\ncrm_ticket --ticket %s --constraints\n\n", + ticket_id); + + offset += snprintf(warning + offset, text_max - offset, + "Otherwise before revoking '%s', you may want to make '%s' standby with:\ncrm_ticket --ticket %s --standby\n", + ticket_id, ticket_id, ticket_id); + word = "from"; + } + + fprintf(stdout, "%s\n", warning); + + while (TRUE) { + char *answer = NULL; + + crm_malloc0(answer, text_max); + fprintf(stdout, "Are you sure you want to %s '%s' %s this site now? (y/n)", + action, ticket_id, word); + + rc = scanf("%s", answer); + + if (strchr(answer, 'y') == answer || strchr(answer, 'Y') == answer) { + rc = TRUE; + crm_free(answer); + goto bail; + + } else if (strchr(answer, 'n') == answer || strchr(answer, 'N') == answer) { + rc = FALSE; + crm_free(answer); + goto bail; + + } else { + crm_free(answer); + fprintf(stdout, "Please answer with y or n\n"); + } + } + +bail: + crm_free(warning); + return rc; +} + +/* *INDENT-OFF* */ +static struct crm_option long_options[] = { + /* Top-level Options */ + {"help", 0, 0, '?', "\t\tThis text"}, + {"version", 0, 0, '$', "\t\tVersion information" }, + {"verbose", 0, 0, 'V', "\t\tIncrease debug output"}, + {"quiet", 0, 0, 'Q', "\t\tPrint only the value on stdout\n"}, + + {"ticket", 1, 0, 't', "\tTicket ID" }, + + {"-spacer-", 1, 0, '-', "\nQueries:"}, + {"info", 0, 0, 'l', "\t\tDisplay the information of ticket(s)"}, + {"details", 0, 0, 'L', "\t\tDisplay the details of ticket(s)"}, + {"raw", 0, 0, 'w', "\t\tDisplay the IDs of ticket(s)"}, + {"query-xml", 0, 0, 'q', "\tQuery the XML of ticket(s)"}, + {"constraints",0, 0, 'c', "\tDisplay the rsc_ticket constraints that apply to ticket(s)"}, + + {"-spacer-", 1, 0, '-', "\nCommands:"}, + {"grant", 0, 0, 'g', "\t\tGrant a ticket to this cluster site"}, + {"revoke", 0, 0, 'r', "\t\tRevoke a ticket from this cluster site"}, + {"standby", 0, 0, 's', "\t\tTell this cluster site this ticket is standby"}, + {"activate", 0, 0, 'a', "\tTell this cluster site this ticket is active"}, + + {"-spacer-", 1, 0, '-', "\nAdvanced Commands:"}, + {"get-attr", 1, 0, 'G', "\tDisplay the named attribute for a ticket"}, + {"set-attr", 1, 0, 'S', "\tSet the named attribtue for a ticket"}, + {"delete-attr",1, 0, 'D', "\tDelete the named attribute for a ticket"}, + {"cleanup", 0, 0, 'C', "\t\tDelete all state of a ticket at this cluster site"}, + + {"-spacer-", 1, 0, '-', "\nAdditional Options:"}, + {"attr-value", 1, 0, 'v', "\tAttribute value to use with -S"}, + {"default", 1, 0, 'd', "\t(Advanced) The default attribute value to display if none is found. For use with -G"}, + {"force", 0, 0, 'f', "\t\t(Advanced) Force the action to be performed"}, + {"xml-file", 1, 0, 'x', NULL, 1},\ + + /* legacy options */ + {"set-name", 1, 0, 'n', "\t(Advanced) ID of the instance_attributes object to change"}, + {"nvpair", 1, 0, 'i', "\t(Advanced) ID of the nvpair object to change/delete"}, + + {"-spacer-", 1, 0, '-', "\nExamples:", pcmk_option_paragraph}, + {"-spacer-", 1, 0, '-', "Display the info of tickets:", pcmk_option_paragraph}, + {"-spacer-", 1, 0, '-', " crm_ticket --info", pcmk_option_example}, + {"-spacer-", 1, 0, '-', "Display the detailed info of tickets:", pcmk_option_paragraph}, + {"-spacer-", 1, 0, '-', " crm_ticket --details", pcmk_option_example}, + {"-spacer-", 1, 0, '-', "Display the XML of 'ticketA':", pcmk_option_paragraph}, + {"-spacer-", 1, 0, '-', " crm_ticket --ticket ticketA --query-xml", pcmk_option_example}, + {"-spacer-", 1, 0, '-', "Display the rsc_ticket constraints that apply to 'ticketA':", pcmk_option_paragraph}, + {"-spacer-", 1, 0, '-', " crm_ticket --ticket ticketA --constraints", pcmk_option_example}, + + {"-spacer-", 1, 0, '-', "Grant 'ticketA' to this cluster site:", pcmk_option_paragraph}, + {"-spacer-", 1, 0, '-', " crm_ticket --ticket ticketA --grant", pcmk_option_example}, + {"-spacer-", 1, 0, '-', "Revoke 'ticketA' from this cluster site:", pcmk_option_paragraph}, + {"-spacer-", 1, 0, '-', " crm_ticket --ticket ticketA --revoke", pcmk_option_example}, + {"-spacer-", 1, 0, '-', "Make 'ticketA' standby:", pcmk_option_paragraph}, + {"-spacer-", 1, 0, '-', "The cluster site will treat a granted 'ticketA' as 'standby'."}, + {"-spacer-", 1, 0, '-', "The dependent resources will be stopped or demoted gracefully without triggering loss-policies", pcmk_option_paragraph}, + {"-spacer-", 1, 0, '-', " crm_ticket --ticket ticketA --standby", pcmk_option_example}, + {"-spacer-", 1, 0, '-', "Activate 'ticketA' from being standby:", pcmk_option_paragraph}, + {"-spacer-", 1, 0, '-', " crm_ticket --ticket ticketA --activate", pcmk_option_example}, + + {"-spacer-", 1, 0, '-', "Get the value of the 'granted' attribute for 'ticketA':", pcmk_option_paragraph}, + {"-spacer-", 1, 0, '-', " crm_ticket --ticket ticketA --get-attr granted", pcmk_option_example}, + {"-spacer-", 1, 0, '-', "Set the value of the 'standby' attribute for 'ticketA':", pcmk_option_paragraph}, + {"-spacer-", 1, 0, '-', " crm_ticket --ticket ticketA --set-attr standby --attr-value true", pcmk_option_example}, + {"-spacer-", 1, 0, '-', "Delete the 'granted' attribute for 'ticketA':", pcmk_option_paragraph}, + {"-spacer-", 1, 0, '-', " crm_ticket --ticket ticketA --delete-attr granted", pcmk_option_example}, + {"-spacer-", 1, 0, '-', "Erase the operation history of 'ticketA' at this cluster site:", pcmk_option_paragraph}, + {"-spacer-", 1, 0, '-', "The cluster site will 'forget' the existing ticket state.", pcmk_option_paragraph}, + {"-spacer-", 1, 0, '-', " crm_ticket --ticket ticketA --cleanup", pcmk_option_example}, + + {0, 0, 0, 0} +}; +/* *INDENT-ON* */ + +int +main(int argc, char **argv) +{ + pe_working_set_t data_set; + xmlNode *cib_xml_copy = NULL; + + cib_t *cib_conn = NULL; + enum cib_errors rc = cib_ok; + + int option_index = 0; + int argerr = 0; + int flag; + + crm_log_init(NULL, LOG_ERR, FALSE, FALSE, argc, argv); + crm_set_options(NULL, "(query|command) [options]", long_options, + "Perform tasks related to cluster tickets.\nAllows ticket attributes to be queried, modified and deleted.\n"); + + if (argc < 2) { + crm_help('?', LSB_EXIT_EINVAL); + } + + while (1) { + flag = crm_get_option(argc, argv, &option_index); + if (flag == -1) + break; + + switch (flag) { + case 'V': + crm_bump_log_level(); + break; + case '$': + case '?': + crm_help(flag, LSB_EXIT_OK); + break; + case 'Q': + BE_QUIET = TRUE; + break; + case 't': + ticket_id = optarg; + break; + case 'l': + case 'L': + case 'w': + case 'q': + case 'c': + ticket_cmd = flag; + break; + case 'g': + case 'r': + case 's': + case 'a': + ticket_cmd = flag; + break; + case 'G': + case 'S': + case 'D': + attr_name = optarg; + ticket_cmd = flag; + break; + case 'C': + ticket_cmd = flag; + break; + case 'v': + attr_value = optarg; + break; + case 'd': + attr_default = optarg; + break; + case 'f': + do_force = TRUE; + break; + case 'x': + xml_file = crm_strdup(optarg); + break; + case 'n': + set_name = optarg; + break; + case 'i': + attr_id = optarg; + break; + + default: + CMD_ERR("Argument code 0%o (%c) is not (?yet?) supported\n", flag, flag); + ++argerr; + break; + } + } + + if (BE_QUIET == FALSE) { + crm_log_args(argc, argv); + } + + if (optind < argc && argv[optind] != NULL) { + CMD_ERR("non-option ARGV-elements: "); + while (optind < argc && argv[optind] != NULL) { + CMD_ERR("%s ", argv[optind++]); + ++argerr; + } + CMD_ERR("\n"); + } + + if (optind > argc) { + ++argerr; + } + + if (argerr) { + crm_help('?', LSB_EXIT_GENERIC); + } + + set_working_set_defaults(&data_set); + + cib_conn = cib_new(); + rc = cib_conn->cmds->signon(cib_conn, crm_system_name, cib_command); + if (rc != cib_ok) { + CMD_ERR("Error signing on to the CIB service: %s\n", cib_error2string(rc)); + return rc; + } + + if (xml_file != NULL) { + cib_xml_copy = filename2xml(xml_file); + + } else { + cib_xml_copy = get_cib_copy(cib_conn); + } + + if (cli_config_update(&cib_xml_copy, NULL, FALSE) == FALSE) { + rc = cib_STALE; + goto bail; + } + + data_set.input = cib_xml_copy; + data_set.now = new_ha_date(TRUE); + + cluster_status(&data_set); + + if (ticket_cmd == 'l' || ticket_cmd == 'L' || ticket_cmd == 'w') { + gboolean raw = FALSE; + gboolean details = FALSE; + rc = cib_ok; + + if (ticket_cmd == 'L') { + details = TRUE; + } else if (ticket_cmd == 'w') { + raw = TRUE; + } + + if (ticket_id) { + ticket_t *ticket = find_ticket(ticket_id, &data_set); + if (ticket == NULL) { + rc = cib_NOTEXISTS; + goto bail; + } + rc = print_ticket(ticket, raw, details); + + } else { + rc = print_ticket_list(&data_set, raw, details); + } + + } else if (ticket_cmd == 'q') { + rc = dump_ticket_xml(cib_conn, ticket_id); + + } else if (ticket_cmd == 'c') { + rc = dump_constraints(cib_conn, ticket_id); + + } else if (ticket_cmd == 'G') { + const char *value = NULL; + + if (ticket_id == NULL) { + CMD_ERR("Must supply a ticket id with -t\n"); + rc = cib_NOTEXISTS; + goto bail; + } + + rc = get_ticket_state_attr(ticket_id, attr_name, &value, &data_set); + if (rc == cib_ok) { + fprintf(stdout, "%s\n", value); + } else if (rc == cib_NOTEXISTS && attr_default) { + fprintf(stdout, "%s\n", attr_default); + rc = cib_ok; + } + + } else if (ticket_cmd == 'S' + || ticket_cmd == 'g' || ticket_cmd == 'r' + || ticket_cmd == 's' || ticket_cmd == 'a') { + gboolean is_granting = FALSE; + + if (ticket_id == NULL) { + CMD_ERR("Must supply a ticket id with -t\n"); + rc = cib_NOTEXISTS; + goto bail; + } + + if (ticket_cmd == 'g') { + attr_name = "granted"; + attr_value = "true"; + + } else if (ticket_cmd == 'r') { + attr_name = "granted"; + attr_value = "false"; + + } else if (ticket_cmd == 's') { + attr_name = "standby"; + attr_value = "true"; + + } else if (ticket_cmd == 'a') { + attr_name = "standby"; + attr_value = "false"; + } + + if (attr_value == NULL || strlen(attr_value) == 0) { + CMD_ERR("You need to supply a value with the -v option\n"); + rc = CIBRES_MISSING_FIELD; + goto bail; + } + + if (safe_str_eq(attr_name, "granted") && do_force == FALSE) { + if (crm_is_true(attr_value) && confirm(ticket_id, "grant") == FALSE) { + CMD_ERR("Cancelled\n"); + rc = cib_ok; + goto bail; + + } else if (crm_is_true(attr_value) == FALSE && confirm(ticket_id, "revoke") == FALSE) { + CMD_ERR("Cancelled\n"); + rc = cib_ok; + goto bail; + } + } + + if (safe_str_eq(attr_name, "granted") && crm_is_true(attr_value)) { + ticket_t *ticket = find_ticket(ticket_id, &data_set); + + if (ticket == NULL || ticket->granted == FALSE) { + is_granting = TRUE; + } + } + + rc = set_ticket_state_attr(ticket_id, attr_name, attr_value, cib_conn); + delete_ticket_state_attr_legacy(ticket_id, set_name, attr_id, attr_name, cib_conn); + + if(rc != cib_ok) { + goto bail; + } + + if (is_granting == TRUE) { + set_ticket_state_attr(ticket_id, "last-granted", crm_itoa(time(NULL)), cib_conn); + delete_ticket_state_attr_legacy(ticket_id, set_name, attr_id, "last-granted", cib_conn); + } + + } else if (ticket_cmd == 'D') { + if (ticket_id == NULL) { + CMD_ERR("Must supply a ticket id with -t\n"); + rc = cib_NOTEXISTS; + goto bail; + } + + if (safe_str_eq(attr_name, "granted") && do_force == FALSE + && confirm(ticket_id, "revoke") == FALSE) { + CMD_ERR("Cancelled\n"); + rc = cib_ok; + goto bail; + } + + delete_ticket_state_attr_legacy(ticket_id, set_name, attr_id, attr_name, cib_conn); + rc = delete_ticket_state_attr(ticket_id, attr_name, cib_conn); + + } else if (ticket_cmd == 'C') { + if (ticket_id == NULL) { + CMD_ERR("Must supply a ticket id with -t\n"); + rc = cib_NOTEXISTS; + goto bail; + } + + if (do_force == FALSE) { + ticket_t *ticket = NULL; + + ticket = find_ticket(ticket_id, &data_set); + if (ticket == NULL) { + return cib_NOTEXISTS; + goto bail; + } + + if (ticket->granted && confirm(ticket_id, "revoke") == FALSE) { + CMD_ERR("Cancelled\n"); + rc = cib_ok; + goto bail; + } + } + + rc = delete_ticket_state(ticket_id, cib_conn); + + } else { + CMD_ERR("Unknown command: %c\n", ticket_cmd); + } + + bail: + + if (cib_conn != NULL) { + cleanup_alloc_calculations(&data_set); + cib_conn->cmds->signoff(cib_conn); + cib_delete(cib_conn); + } + + crm_xml_cleanup(); + + if (rc == cib_no_quorum) { + CMD_ERR("Error performing operation: %s\n", cib_error2string(rc)); + CMD_ERR("Try using -f\n"); + + } else if (rc != cib_ok) { + CMD_ERR("Error performing operation: %s\n", cib_error2string(rc)); + } + + return rc; +}
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor