diff --git a/cts/cli/regression.rules.exp b/cts/cli/regression.rules.exp index cdfb5d1e24..a439773cfe 100644 --- a/cts/cli/regression.rules.exp +++ b/cts/cli/regression.rules.exp @@ -1,289 +1,285 @@ Created new pacemaker configuration A new shadow instance was created. To begin using it, enter the following into your shell: export CIB_shadow=cts-cli =#=#=#= Begin test: crm_rule given no arguments =#=#=#= crm_rule: No mode operation given =#=#=#= End test: crm_rule given no arguments - Incorrect usage (64) =#=#=#= * Passed: crm_rule - crm_rule given no arguments =#=#=#= Begin test: crm_rule given no arguments (XML) =#=#=#= crm_rule: No mode operation given =#=#=#= End test: crm_rule given no arguments (XML) - Incorrect usage (64) =#=#=#= * Passed: crm_rule - crm_rule given no arguments (XML) =#=#=#= Begin test: crm_rule given no rule to check =#=#=#= crm_rule: --check requires use of --rule= =#=#=#= End test: crm_rule given no rule to check - Incorrect usage (64) =#=#=#= * Passed: crm_rule - crm_rule given no rule to check =#=#=#= Begin test: crm_rule given no rule to check (XML) =#=#=#= crm_rule: --check requires use of --rule= =#=#=#= End test: crm_rule given no rule to check (XML) - Incorrect usage (64) =#=#=#= * Passed: crm_rule - crm_rule given no rule to check (XML) =#=#=#= Begin test: crm_rule given invalid input XML =#=#=#= log_xmllib_err error: XML Error: Entity: line 1: parser error : Start tag expected, '<' not found log_xmllib_err error: XML Error: invalidxml log_xmllib_err error: XML Error: ^ log_xmllib_err error: XML Error: Entity: line 1: parser error : Start tag expected, '<' not found log_xmllib_err error: XML Error: invalidxml log_xmllib_err error: XML Error: ^ crm_rule: Couldn't parse input string: invalidxml - =#=#=#= End test: crm_rule given invalid input XML - Invalid data given (65) =#=#=#= * Passed: crm_rule - crm_rule given invalid input XML =#=#=#= Begin test: crm_rule given invalid input XML (XML) =#=#=#= log_xmllib_err error: XML Error: Entity: line 1: parser error : Start tag expected, '<' not found log_xmllib_err error: XML Error: invalidxml log_xmllib_err error: XML Error: ^ log_xmllib_err error: XML Error: Entity: line 1: parser error : Start tag expected, '<' not found log_xmllib_err error: XML Error: invalidxml log_xmllib_err error: XML Error: ^ - crm_rule: Couldn't parse input string: invalidxml - + crm_rule: Couldn't parse input string: invalidxml =#=#=#= End test: crm_rule given invalid input XML (XML) - Invalid data given (65) =#=#=#= * Passed: crm_rule - crm_rule given invalid input XML (XML) =#=#=#= Begin test: crm_rule given invalid input XML on stdin =#=#=#= log_xmllib_err error: XML Error: Entity: line 1: parser error : Start tag expected, '<' not found log_xmllib_err error: XML Error: invalidxml log_xmllib_err error: XML Error: ^ log_xmllib_err error: XML Error: Entity: line 1: parser error : Start tag expected, '<' not found log_xmllib_err error: XML Error: invalidxml log_xmllib_err error: XML Error: ^ crm_rule: Couldn't parse input from STDIN - =#=#=#= End test: crm_rule given invalid input XML on stdin - Invalid data given (65) =#=#=#= * Passed: echo - crm_rule given invalid input XML on stdin =#=#=#= Begin test: crm_rule given invalid input XML on stdin (XML) =#=#=#= log_xmllib_err error: XML Error: Entity: line 1: parser error : Start tag expected, '<' not found log_xmllib_err error: XML Error: invalidxml log_xmllib_err error: XML Error: ^ log_xmllib_err error: XML Error: Entity: line 1: parser error : Start tag expected, '<' not found log_xmllib_err error: XML Error: invalidxml log_xmllib_err error: XML Error: ^ - crm_rule: Couldn't parse input from STDIN - + crm_rule: Couldn't parse input from STDIN =#=#=#= End test: crm_rule given invalid input XML on stdin (XML) - Invalid data given (65) =#=#=#= * Passed: echo - crm_rule given invalid input XML on stdin (XML) =#=#=#= Begin test: Try to check a rule that doesn't exist =#=#=#= Could not determine whether rule blahblah is in effect: Rule not found =#=#=#= Current cib after: Try to check a rule that doesn't exist =#=#=#= =#=#=#= End test: Try to check a rule that doesn't exist - No such object (105) =#=#=#= * Passed: crm_rule - Try to check a rule that doesn't exist =#=#=#= Begin test: Try to check a rule that doesn't exist, with XML output =#=#=#= Could not determine whether rule blahblah is in effect: Rule not found =#=#=#= End test: Try to check a rule that doesn't exist, with XML output - No such object (105) =#=#=#= * Passed: crm_rule - Try to check a rule that doesn't exist, with XML output =#=#=#= Begin test: Try to check a rule that has too many date_expressions =#=#=#= Could not determine whether rule cli-rule-too-many-date-expressions is in effect: Rule has more than one date expression =#=#=#= End test: Try to check a rule that has too many date_expressions - Unimplemented (3) =#=#=#= * Passed: crm_rule - Try to check a rule that has too many date_expressions =#=#=#= Begin test: Try to check a rule that has too many date_expressions (XML) =#=#=#= Could not determine whether rule cli-rule-too-many-date-expressions is in effect: Rule has more than one date expression =#=#=#= End test: Try to check a rule that has too many date_expressions (XML) - Unimplemented (3) =#=#=#= * Passed: crm_rule - Try to check a rule that has too many date_expressions (XML) =#=#=#= Begin test: Verify basic rule is expired =#=#=#= Rule cli-prefer-rule-dummy-expired is expired =#=#=#= End test: Verify basic rule is expired - Requested item has expired (110) =#=#=#= * Passed: crm_rule - Verify basic rule is expired =#=#=#= Begin test: Verify basic rule is expired, with XML output =#=#=#= =#=#=#= End test: Verify basic rule is expired, with XML output - Requested item has expired (110) =#=#=#= * Passed: crm_rule - Verify basic rule is expired, with XML output =#=#=#= Begin test: Verify basic rule worked in the past =#=#=#= Rule cli-prefer-rule-dummy-expired is still in effect =#=#=#= End test: Verify basic rule worked in the past - OK (0) =#=#=#= * Passed: crm_rule - Verify basic rule worked in the past =#=#=#= Begin test: Verify basic rule worked in the past (XML) =#=#=#= =#=#=#= End test: Verify basic rule worked in the past (XML) - OK (0) =#=#=#= * Passed: crm_rule - Verify basic rule worked in the past (XML) =#=#=#= Begin test: Verify basic rule is not yet in effect =#=#=#= Rule cli-prefer-rule-dummy-not-yet has not yet taken effect =#=#=#= End test: Verify basic rule is not yet in effect - Requested item is not yet in effect (111) =#=#=#= * Passed: crm_rule - Verify basic rule is not yet in effect =#=#=#= Begin test: Verify basic rule is not yet in effect (XML) =#=#=#= =#=#=#= End test: Verify basic rule is not yet in effect (XML) - Requested item is not yet in effect (111) =#=#=#= * Passed: crm_rule - Verify basic rule is not yet in effect (XML) =#=#=#= Begin test: Verify date_spec rule with years has expired =#=#=#= Rule cli-prefer-rule-dummy-date_spec-only-years is expired =#=#=#= End test: Verify date_spec rule with years has expired - Requested item has expired (110) =#=#=#= * Passed: crm_rule - Verify date_spec rule with years has expired =#=#=#= Begin test: Verify date_spec rule with years has expired (XML) =#=#=#= =#=#=#= End test: Verify date_spec rule with years has expired (XML) - Requested item has expired (110) =#=#=#= * Passed: crm_rule - Verify date_spec rule with years has expired (XML) =#=#=#= Begin test: Verify multiple rules at once =#=#=#= Rule cli-prefer-rule-dummy-not-yet has not yet taken effect Rule cli-prefer-rule-dummy-date_spec-only-years is expired =#=#=#= End test: Verify multiple rules at once - Requested item has expired (110) =#=#=#= * Passed: crm_rule - Verify multiple rules at once =#=#=#= Begin test: Verify multiple rules at once, with XML output =#=#=#= =#=#=#= End test: Verify multiple rules at once, with XML output - Requested item has expired (110) =#=#=#= * Passed: crm_rule - Verify multiple rules at once, with XML output =#=#=#= Begin test: Verify date_spec rule with years is in effect =#=#=#= Rule cli-prefer-rule-dummy-date_spec-only-years satisfies conditions =#=#=#= End test: Verify date_spec rule with years is in effect - OK (0) =#=#=#= * Passed: crm_rule - Verify date_spec rule with years is in effect =#=#=#= Begin test: Verify date_spec rule with years is in effect (XML) =#=#=#= =#=#=#= End test: Verify date_spec rule with years is in effect (XML) - OK (0) =#=#=#= * Passed: crm_rule - Verify date_spec rule with years is in effect (XML) =#=#=#= Begin test: Try to check a rule whose date_spec does not contain years= =#=#=#= Could not determine whether rule cli-prefer-rule-dummy-date_spec-without-years is in effect: Rule must either not use date_spec, or use date_spec with years= but not moon= =#=#=#= End test: Try to check a rule whose date_spec does not contain years= - Unimplemented (3) =#=#=#= * Passed: crm_rule - Try to check a rule whose date_spec does not contain years= =#=#=#= Begin test: Try to check a rule whose date_spec does not contain years= (XML) =#=#=#= Could not determine whether rule cli-prefer-rule-dummy-date_spec-without-years is in effect: Rule must either not use date_spec, or use date_spec with years= but not moon= =#=#=#= End test: Try to check a rule whose date_spec does not contain years= (XML) - Unimplemented (3) =#=#=#= * Passed: crm_rule - Try to check a rule whose date_spec does not contain years= (XML) =#=#=#= Begin test: Try to check a rule whose date_spec contains years= and moon= =#=#=#= Could not determine whether rule cli-prefer-rule-dummy-date_spec-years-moon is in effect: Rule must either not use date_spec, or use date_spec with years= but not moon= =#=#=#= End test: Try to check a rule whose date_spec contains years= and moon= - Unimplemented (3) =#=#=#= * Passed: crm_rule - Try to check a rule whose date_spec contains years= and moon= =#=#=#= Begin test: Try to check a rule whose date_spec contains years= and moon= (XML) =#=#=#= Could not determine whether rule cli-prefer-rule-dummy-date_spec-years-moon is in effect: Rule must either not use date_spec, or use date_spec with years= but not moon= =#=#=#= End test: Try to check a rule whose date_spec contains years= and moon= (XML) - Unimplemented (3) =#=#=#= * Passed: crm_rule - Try to check a rule whose date_spec contains years= and moon= (XML) =#=#=#= Begin test: Try to check a rule with no date_expression =#=#=#= Could not determine whether rule cli-no-date_expression-rule is in effect: Rule does not have a date expression =#=#=#= End test: Try to check a rule with no date_expression - Unimplemented (3) =#=#=#= * Passed: crm_rule - Try to check a rule with no date_expression =#=#=#= Begin test: Try to check a rule with no date_expression (XML) =#=#=#= Could not determine whether rule cli-no-date_expression-rule is in effect: Rule does not have a date expression =#=#=#= End test: Try to check a rule with no date_expression (XML) - Unimplemented (3) =#=#=#= * Passed: crm_rule - Try to check a rule with no date_expression (XML) diff --git a/tools/crm_rule.c b/tools/crm_rule.c index eb8f3f0765..2a735c1352 100644 --- a/tools/crm_rule.c +++ b/tools/crm_rule.c @@ -1,227 +1,228 @@ /* * Copyright 2019-2024 the Pacemaker project contributors * * The version control history for this file may have further details. * * This source code is licensed under the GNU General Public License version 2 * or later (GPLv2+) WITHOUT ANY WARRANTY. */ #include #include #include #include #include #include #include #include #include #define SUMMARY "evaluate rules from the Pacemaker configuration" static pcmk__supported_format_t formats[] = { PCMK__SUPPORTED_FORMAT_NONE, PCMK__SUPPORTED_FORMAT_TEXT, PCMK__SUPPORTED_FORMAT_XML, { NULL, NULL, NULL } }; enum crm_rule_mode { crm_rule_mode_none, crm_rule_mode_check }; struct { char *date; char *input_xml; enum crm_rule_mode mode; gchar **rules; } options = { .mode = crm_rule_mode_none }; static gboolean mode_cb(const gchar *option_name, const gchar *optarg, gpointer data, GError **error); static GOptionEntry mode_entries[] = { { "check", 'c', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, mode_cb, "Check whether a rule is in effect", NULL }, { NULL } }; static GOptionEntry data_entries[] = { { "xml-text", 'X', 0, G_OPTION_ARG_STRING, &options.input_xml, "Use argument for XML (or stdin if '-')", NULL }, { NULL } }; static GOptionEntry addl_entries[] = { { "date", 'd', 0, G_OPTION_ARG_STRING, &options.date, "Whether the rule is in effect on a given date", NULL }, { "rule", 'r', 0, G_OPTION_ARG_STRING_ARRAY, &options.rules, "The ID of the rule to check (may be specified multiple times)", NULL }, { NULL } }; static gboolean mode_cb(const gchar *option_name, const gchar *optarg, gpointer data, GError **error) { if (strcmp(option_name, "c")) { options.mode = crm_rule_mode_check; } return TRUE; } static GOptionContext * build_arg_context(pcmk__common_args_t *args, GOptionGroup **group) { GOptionContext *context = NULL; context = pcmk__build_arg_context(args, "text (default), xml", group, NULL); pcmk__add_arg_group(context, "modes", "Modes (mutually exclusive):", "Show modes of operation", mode_entries); pcmk__add_arg_group(context, "data", "Data:", "Show data options", data_entries); pcmk__add_arg_group(context, "additional", "Additional Options:", "Show additional options", addl_entries); return context; } int main(int argc, char **argv) { crm_time_t *rule_date = NULL; xmlNode *input = NULL; int rc = pcmk_rc_ok; crm_exit_t exit_code = CRM_EX_OK; GError *error = NULL; pcmk__output_t *out = NULL; GOptionGroup *output_group = NULL; pcmk__common_args_t *args = pcmk__new_common_args(SUMMARY); GOptionContext *context = build_arg_context(args, &output_group); gchar **processed_args = pcmk__cmdline_preproc(argv, "drX"); pcmk__register_formats(output_group, formats); if (!g_option_context_parse_strv(context, &processed_args, &error)) { exit_code = CRM_EX_USAGE; goto done; } pcmk__cli_init_logging("crm_rule", args->verbosity); rc = pcmk__output_new(&out, args->output_ty, args->output_dest, argv); if (rc != pcmk_rc_ok) { exit_code = CRM_EX_ERROR; g_set_error(&error, PCMK__EXITC_ERROR, exit_code, "Error creating output format %s: %s", args->output_ty, pcmk_rc_str(rc)); goto done; } pcmk__register_lib_messages(out); if (args->version) { out->version(out, false); goto done; } /* Check command line arguments before opening a connection to * the CIB manager or doing anything else important. */ switch(options.mode) { case crm_rule_mode_check: if (options.rules == NULL) { exit_code = CRM_EX_USAGE; g_set_error(&error, PCMK__EXITC_ERROR, exit_code, "--check requires use of --rule="); goto done; } break; default: exit_code = CRM_EX_USAGE; g_set_error(&error, PCMK__EXITC_ERROR, exit_code, "No mode operation given"); goto done; break; } /* Set up some defaults. */ rule_date = crm_time_new(options.date); if (rule_date == NULL) { if (options.date != NULL) { exit_code = CRM_EX_DATAERR; g_set_error(&error, PCMK__EXITC_ERROR, exit_code, "Invalid date specified: '%s'", options.date); } else { // Should never happen exit_code = CRM_EX_OSERR; g_set_error(&error, PCMK__EXITC_ERROR, exit_code, "No --date given and can't determine current date"); } goto done; } // Parse the input XML specified by the command-line options, if any if (pcmk__str_eq(options.input_xml, "-", pcmk__str_casei)) { input = stdin2xml(); if (input == NULL) { exit_code = CRM_EX_DATAERR; - g_set_error(&error, PCMK__EXITC_ERROR, exit_code, "Couldn't parse input from STDIN\n"); + g_set_error(&error, PCMK__EXITC_ERROR, exit_code, + "Couldn't parse input from STDIN"); goto done; } } else if (options.input_xml != NULL) { input = string2xml(options.input_xml); if (input == NULL) { exit_code = CRM_EX_DATAERR; g_set_error(&error, PCMK__EXITC_ERROR, exit_code, - "Couldn't parse input string: %s\n", options.input_xml); + "Couldn't parse input string: %s", options.input_xml); goto done; } } /* Now do whichever operation mode was asked for. There's only one at the * moment so this looks a little silly, but I expect there will be more * modes in the future. */ switch(options.mode) { case crm_rule_mode_check: rc = pcmk__check_rules(out, input, rule_date, (const char **) options.rules); exit_code = pcmk_rc2exitc(rc); break; default: break; } done: g_strfreev(processed_args); pcmk__free_arg_context(context); crm_time_free(rule_date); free_xml(input); pcmk__output_and_clear_error(&error, out); if (out != NULL) { out->finish(out, exit_code, true, NULL); pcmk__output_free(out); } pcmk__unregister_formats(); return crm_exit(exit_code); }