4948 lines
		
	
	
		
			194 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			4948 lines
		
	
	
		
			194 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 2f10dde2f2a0ac7a3d74cb2f398be1deaba75615 Mon Sep 17 00:00:00 2001
 | |
| From: Chris Lumens <clumens@redhat.com>
 | |
| Date: Mon, 6 Apr 2020 11:22:50 -0400
 | |
| Subject: [PATCH 01/17] Feature: scheduler: Add new expression_type values.
 | |
| 
 | |
| ---
 | |
|  include/crm/pengine/rules.h | 4 +++-
 | |
|  lib/pengine/rules.c         | 6 ++++++
 | |
|  2 files changed, 9 insertions(+), 1 deletion(-)
 | |
| 
 | |
| diff --git a/include/crm/pengine/rules.h b/include/crm/pengine/rules.h
 | |
| index ebd3148..37f092b 100644
 | |
| --- a/include/crm/pengine/rules.h
 | |
| +++ b/include/crm/pengine/rules.h
 | |
| @@ -28,7 +28,9 @@ enum expression_type {
 | |
|      loc_expr,
 | |
|      role_expr,
 | |
|      time_expr,
 | |
| -    version_expr
 | |
| +    version_expr,
 | |
| +    rsc_expr,
 | |
| +    op_expr
 | |
|  };
 | |
|  
 | |
|  typedef struct pe_re_match_data {
 | |
| diff --git a/lib/pengine/rules.c b/lib/pengine/rules.c
 | |
| index fa9a222..130bada 100644
 | |
| --- a/lib/pengine/rules.c
 | |
| +++ b/lib/pengine/rules.c
 | |
| @@ -189,6 +189,12 @@ find_expression_type(xmlNode * expr)
 | |
|      if (safe_str_eq(tag, "date_expression")) {
 | |
|          return time_expr;
 | |
|  
 | |
| +    } else if (safe_str_eq(tag, "rsc_expression")) {
 | |
| +        return rsc_expr;
 | |
| +
 | |
| +    } else if (safe_str_eq(tag, "op_expression")) {
 | |
| +        return op_expr;
 | |
| +
 | |
|      } else if (safe_str_eq(tag, XML_TAG_RULE)) {
 | |
|          return nested_rule;
 | |
|  
 | |
| -- 
 | |
| 1.8.3.1
 | |
| 
 | |
| 
 | |
| From bc7491e5226af2a2e7f1a9b2d61892d3af0767fe Mon Sep 17 00:00:00 2001
 | |
| From: Chris Lumens <clumens@redhat.com>
 | |
| Date: Fri, 3 Apr 2020 15:03:23 -0400
 | |
| Subject: [PATCH 02/17] Refactor: scheduler: Add new pe__eval_*_expr functions.
 | |
| 
 | |
| These new functions all take the same input arguments - an xmlNodePtr
 | |
| and a pe_rule_eval_data_t.  This latter type holds all the parameters
 | |
| that could possibly be useful for evaluating some rule.  Most functions
 | |
| will only need a few items out of this structure.
 | |
| 
 | |
| Then, implement pe_test_*_expression in terms of these new functions.
 | |
| ---
 | |
|  include/crm/pengine/common.h         |  37 ++-
 | |
|  include/crm/pengine/rules.h          |  13 -
 | |
|  include/crm/pengine/rules_internal.h |   5 +
 | |
|  lib/pengine/rules.c                  | 592 +++++++++++++++++++----------------
 | |
|  4 files changed, 363 insertions(+), 284 deletions(-)
 | |
| 
 | |
| diff --git a/include/crm/pengine/common.h b/include/crm/pengine/common.h
 | |
| index 48c2b66..3a770b7 100644
 | |
| --- a/include/crm/pengine/common.h
 | |
| +++ b/include/crm/pengine/common.h
 | |
| @@ -1,5 +1,5 @@
 | |
|  /*
 | |
| - * Copyright 2004-2019 the Pacemaker project contributors
 | |
| + * Copyright 2004-2020 the Pacemaker project contributors
 | |
|   *
 | |
|   * The version control history for this file may have further details.
 | |
|   *
 | |
| @@ -15,6 +15,9 @@ extern "C" {
 | |
|  #endif
 | |
|  
 | |
|  #  include <glib.h>
 | |
| +#  include <regex.h>
 | |
| +
 | |
| +#  include <crm/common/iso8601.h>
 | |
|  
 | |
|  extern gboolean was_processing_error;
 | |
|  extern gboolean was_processing_warning;
 | |
| @@ -131,6 +134,38 @@ recovery2text(enum rsc_recovery_type type)
 | |
|      return "Unknown";
 | |
|  }
 | |
|  
 | |
| +typedef struct pe_re_match_data {
 | |
| +    char *string;
 | |
| +    int nregs;
 | |
| +    regmatch_t *pmatch;
 | |
| +} pe_re_match_data_t;
 | |
| +
 | |
| +typedef struct pe_match_data {
 | |
| +    pe_re_match_data_t *re;
 | |
| +    GHashTable *params;
 | |
| +    GHashTable *meta;
 | |
| +} pe_match_data_t;
 | |
| +
 | |
| +typedef struct pe_rsc_eval_data {
 | |
| +    const char *standard;
 | |
| +    const char *provider;
 | |
| +    const char *agent;
 | |
| +} pe_rsc_eval_data_t;
 | |
| +
 | |
| +typedef struct pe_op_eval_data {
 | |
| +    const char *op_name;
 | |
| +    guint interval;
 | |
| +} pe_op_eval_data_t;
 | |
| +
 | |
| +typedef struct pe_rule_eval_data {
 | |
| +    GHashTable *node_hash;
 | |
| +    enum rsc_role_e role;
 | |
| +    crm_time_t *now;
 | |
| +    pe_match_data_t *match_data;
 | |
| +    pe_rsc_eval_data_t *rsc_data;
 | |
| +    pe_op_eval_data_t *op_data;
 | |
| +} pe_rule_eval_data_t;
 | |
| +
 | |
|  #ifdef __cplusplus
 | |
|  }
 | |
|  #endif
 | |
| diff --git a/include/crm/pengine/rules.h b/include/crm/pengine/rules.h
 | |
| index 37f092b..d7bdbf9 100644
 | |
| --- a/include/crm/pengine/rules.h
 | |
| +++ b/include/crm/pengine/rules.h
 | |
| @@ -15,7 +15,6 @@ extern "C" {
 | |
|  #endif
 | |
|  
 | |
|  #  include <glib.h>
 | |
| -#  include <regex.h>
 | |
|  
 | |
|  #  include <crm/crm.h>
 | |
|  #  include <crm/common/iso8601.h>
 | |
| @@ -33,18 +32,6 @@ enum expression_type {
 | |
|      op_expr
 | |
|  };
 | |
|  
 | |
| -typedef struct pe_re_match_data {
 | |
| -    char *string;
 | |
| -    int nregs;
 | |
| -    regmatch_t *pmatch;
 | |
| -} pe_re_match_data_t;
 | |
| -
 | |
| -typedef struct pe_match_data {
 | |
| -    pe_re_match_data_t *re;
 | |
| -    GHashTable *params;
 | |
| -    GHashTable *meta;
 | |
| -} pe_match_data_t;
 | |
| -
 | |
|  enum expression_type find_expression_type(xmlNode * expr);
 | |
|  
 | |
|  gboolean pe_evaluate_rules(xmlNode *ruleset, GHashTable *node_hash,
 | |
| diff --git a/include/crm/pengine/rules_internal.h b/include/crm/pengine/rules_internal.h
 | |
| index fd65c1e..8a22108 100644
 | |
| --- a/include/crm/pengine/rules_internal.h
 | |
| +++ b/include/crm/pengine/rules_internal.h
 | |
| @@ -21,6 +21,11 @@ void pe_free_alert_list(GListPtr alert_list);
 | |
|  
 | |
|  crm_time_t *pe_parse_xml_duration(crm_time_t * start, xmlNode * duration_spec);
 | |
|  
 | |
| +gboolean pe__eval_attr_expr(xmlNode *expr, pe_rule_eval_data_t *rule_data);
 | |
| +int pe__eval_date_expr(xmlNode *expr, pe_rule_eval_data_t *rule_data,
 | |
| +                       crm_time_t *next_change);
 | |
| +gboolean pe__eval_role_expr(xmlNode *expr, pe_rule_eval_data_t *rule_data);
 | |
| +
 | |
|  int pe_eval_date_expression(xmlNode *time_expr,
 | |
|                              crm_time_t *now,
 | |
|                              crm_time_t *next_change);
 | |
| diff --git a/lib/pengine/rules.c b/lib/pengine/rules.c
 | |
| index 130bada..3f316c2 100644
 | |
| --- a/lib/pengine/rules.c
 | |
| +++ b/lib/pengine/rules.c
 | |
| @@ -219,201 +219,34 @@ find_expression_type(xmlNode * expr)
 | |
|  }
 | |
|  
 | |
|  gboolean
 | |
| -pe_test_role_expression(xmlNode * expr, enum rsc_role_e role, crm_time_t * now)
 | |
| +pe_test_role_expression(xmlNode *expr, enum rsc_role_e role, crm_time_t *now)
 | |
|  {
 | |
| -    gboolean accept = FALSE;
 | |
| -    const char *op = NULL;
 | |
| -    const char *value = NULL;
 | |
| -
 | |
| -    if (role == RSC_ROLE_UNKNOWN) {
 | |
| -        return accept;
 | |
| -    }
 | |
| -
 | |
| -    value = crm_element_value(expr, XML_EXPR_ATTR_VALUE);
 | |
| -    op = crm_element_value(expr, XML_EXPR_ATTR_OPERATION);
 | |
| -
 | |
| -    if (safe_str_eq(op, "defined")) {
 | |
| -        if (role > RSC_ROLE_STARTED) {
 | |
| -            accept = TRUE;
 | |
| -        }
 | |
| -
 | |
| -    } else if (safe_str_eq(op, "not_defined")) {
 | |
| -        if (role < RSC_ROLE_SLAVE && role > RSC_ROLE_UNKNOWN) {
 | |
| -            accept = TRUE;
 | |
| -        }
 | |
| -
 | |
| -    } else if (safe_str_eq(op, "eq")) {
 | |
| -        if (text2role(value) == role) {
 | |
| -            accept = TRUE;
 | |
| -        }
 | |
| -
 | |
| -    } else if (safe_str_eq(op, "ne")) {
 | |
| -        // Test "ne" only with promotable clone roles
 | |
| -        if (role < RSC_ROLE_SLAVE && role > RSC_ROLE_UNKNOWN) {
 | |
| -            accept = FALSE;
 | |
| -
 | |
| -        } else if (text2role(value) != role) {
 | |
| -            accept = TRUE;
 | |
| -        }
 | |
| -    }
 | |
| -    return accept;
 | |
| +    pe_rule_eval_data_t rule_data = {
 | |
| +        .node_hash = NULL,
 | |
| +        .role = role,
 | |
| +        .now = now,
 | |
| +        .match_data = NULL,
 | |
| +        .rsc_data = NULL,
 | |
| +        .op_data = NULL
 | |
| +    };
 | |
| +
 | |
| +    return pe__eval_role_expr(expr, &rule_data);
 | |
|  }
 | |
|  
 | |
|  gboolean
 | |
|  pe_test_attr_expression(xmlNode *expr, GHashTable *hash, crm_time_t *now,
 | |
|                          pe_match_data_t *match_data)
 | |
|  {
 | |
| -    gboolean accept = FALSE;
 | |
| -    gboolean attr_allocated = FALSE;
 | |
| -    int cmp = 0;
 | |
| -    const char *h_val = NULL;
 | |
| -    GHashTable *table = NULL;
 | |
| -
 | |
| -    const char *op = NULL;
 | |
| -    const char *type = NULL;
 | |
| -    const char *attr = NULL;
 | |
| -    const char *value = NULL;
 | |
| -    const char *value_source = NULL;
 | |
| -
 | |
| -    attr = crm_element_value(expr, XML_EXPR_ATTR_ATTRIBUTE);
 | |
| -    op = crm_element_value(expr, XML_EXPR_ATTR_OPERATION);
 | |
| -    value = crm_element_value(expr, XML_EXPR_ATTR_VALUE);
 | |
| -    type = crm_element_value(expr, XML_EXPR_ATTR_TYPE);
 | |
| -    value_source = crm_element_value(expr, XML_EXPR_ATTR_VALUE_SOURCE);
 | |
| -
 | |
| -    if (attr == NULL || op == NULL) {
 | |
| -        pe_err("Invalid attribute or operation in expression"
 | |
| -               " (\'%s\' \'%s\' \'%s\')", crm_str(attr), crm_str(op), crm_str(value));
 | |
| -        return FALSE;
 | |
| -    }
 | |
| -
 | |
| -    if (match_data) {
 | |
| -        if (match_data->re) {
 | |
| -            char *resolved_attr = pe_expand_re_matches(attr, match_data->re);
 | |
| -
 | |
| -            if (resolved_attr) {
 | |
| -                attr = (const char *) resolved_attr;
 | |
| -                attr_allocated = TRUE;
 | |
| -            }
 | |
| -        }
 | |
| -
 | |
| -        if (safe_str_eq(value_source, "param")) {
 | |
| -            table = match_data->params;
 | |
| -        } else if (safe_str_eq(value_source, "meta")) {
 | |
| -            table = match_data->meta;
 | |
| -        }
 | |
| -    }
 | |
| -
 | |
| -    if (table) {
 | |
| -        const char *param_name = value;
 | |
| -        const char *param_value = NULL;
 | |
| -
 | |
| -        if (param_name && param_name[0]) {
 | |
| -            if ((param_value = (const char *)g_hash_table_lookup(table, param_name))) {
 | |
| -                value = param_value;
 | |
| -            }
 | |
| -        }
 | |
| -    }
 | |
| -
 | |
| -    if (hash != NULL) {
 | |
| -        h_val = (const char *)g_hash_table_lookup(hash, attr);
 | |
| -    }
 | |
| -
 | |
| -    if (attr_allocated) {
 | |
| -        free((char *)attr);
 | |
| -        attr = NULL;
 | |
| -    }
 | |
| -
 | |
| -    if (value != NULL && h_val != NULL) {
 | |
| -        if (type == NULL) {
 | |
| -            if (safe_str_eq(op, "lt")
 | |
| -                || safe_str_eq(op, "lte")
 | |
| -                || safe_str_eq(op, "gt")
 | |
| -                || safe_str_eq(op, "gte")) {
 | |
| -                type = "number";
 | |
| -
 | |
| -            } else {
 | |
| -                type = "string";
 | |
| -            }
 | |
| -            crm_trace("Defaulting to %s based comparison for '%s' op", type, op);
 | |
| -        }
 | |
| -
 | |
| -        if (safe_str_eq(type, "string")) {
 | |
| -            cmp = strcasecmp(h_val, value);
 | |
| -
 | |
| -        } else if (safe_str_eq(type, "number")) {
 | |
| -            int h_val_f = crm_parse_int(h_val, NULL);
 | |
| -            int value_f = crm_parse_int(value, NULL);
 | |
| -
 | |
| -            if (h_val_f < value_f) {
 | |
| -                cmp = -1;
 | |
| -            } else if (h_val_f > value_f) {
 | |
| -                cmp = 1;
 | |
| -            } else {
 | |
| -                cmp = 0;
 | |
| -            }
 | |
| -
 | |
| -        } else if (safe_str_eq(type, "version")) {
 | |
| -            cmp = compare_version(h_val, value);
 | |
| -
 | |
| -        }
 | |
| -
 | |
| -    } else if (value == NULL && h_val == NULL) {
 | |
| -        cmp = 0;
 | |
| -    } else if (value == NULL) {
 | |
| -        cmp = 1;
 | |
| -    } else {
 | |
| -        cmp = -1;
 | |
| -    }
 | |
| -
 | |
| -    if (safe_str_eq(op, "defined")) {
 | |
| -        if (h_val != NULL) {
 | |
| -            accept = TRUE;
 | |
| -        }
 | |
| -
 | |
| -    } else if (safe_str_eq(op, "not_defined")) {
 | |
| -        if (h_val == NULL) {
 | |
| -            accept = TRUE;
 | |
| -        }
 | |
| -
 | |
| -    } else if (safe_str_eq(op, "eq")) {
 | |
| -        if ((h_val == value) || cmp == 0) {
 | |
| -            accept = TRUE;
 | |
| -        }
 | |
| -
 | |
| -    } else if (safe_str_eq(op, "ne")) {
 | |
| -        if ((h_val == NULL && value != NULL)
 | |
| -            || (h_val != NULL && value == NULL)
 | |
| -            || cmp != 0) {
 | |
| -            accept = TRUE;
 | |
| -        }
 | |
| -
 | |
| -    } else if (value == NULL || h_val == NULL) {
 | |
| -        // The comparison is meaningless from this point on
 | |
| -        accept = FALSE;
 | |
| -
 | |
| -    } else if (safe_str_eq(op, "lt")) {
 | |
| -        if (cmp < 0) {
 | |
| -            accept = TRUE;
 | |
| -        }
 | |
| -
 | |
| -    } else if (safe_str_eq(op, "lte")) {
 | |
| -        if (cmp <= 0) {
 | |
| -            accept = TRUE;
 | |
| -        }
 | |
| -
 | |
| -    } else if (safe_str_eq(op, "gt")) {
 | |
| -        if (cmp > 0) {
 | |
| -            accept = TRUE;
 | |
| -        }
 | |
| -
 | |
| -    } else if (safe_str_eq(op, "gte")) {
 | |
| -        if (cmp >= 0) {
 | |
| -            accept = TRUE;
 | |
| -        }
 | |
| -    }
 | |
| -
 | |
| -    return accept;
 | |
| +    pe_rule_eval_data_t rule_data = {
 | |
| +        .node_hash = hash,
 | |
| +        .role = RSC_ROLE_UNKNOWN,
 | |
| +        .now = now,
 | |
| +        .match_data = match_data,
 | |
| +        .rsc_data = NULL,
 | |
| +        .op_data = NULL
 | |
| +    };
 | |
| +
 | |
| +    return pe__eval_attr_expr(expr, &rule_data);
 | |
|  }
 | |
|  
 | |
|  /* As per the nethack rules:
 | |
| @@ -587,10 +420,18 @@ pe_parse_xml_duration(crm_time_t * start, xmlNode * duration_spec)
 | |
|   * \return TRUE if date expression is in effect at given time, FALSE otherwise
 | |
|   */
 | |
|  gboolean
 | |
| -pe_test_date_expression(xmlNode *time_expr, crm_time_t *now,
 | |
| -                        crm_time_t *next_change)
 | |
| +pe_test_date_expression(xmlNode *expr, crm_time_t *now, crm_time_t *next_change)
 | |
|  {
 | |
| -    switch (pe_eval_date_expression(time_expr, now, next_change)) {
 | |
| +    pe_rule_eval_data_t rule_data = {
 | |
| +        .node_hash = NULL,
 | |
| +        .role = RSC_ROLE_UNKNOWN,
 | |
| +        .now = now,
 | |
| +        .match_data = NULL,
 | |
| +        .rsc_data = NULL,
 | |
| +        .op_data = NULL
 | |
| +    };
 | |
| +
 | |
| +    switch (pe__eval_date_expr(expr, &rule_data, next_change)) {
 | |
|          case pcmk_rc_within_range:
 | |
|          case pcmk_rc_ok:
 | |
|              return TRUE;
 | |
| @@ -623,86 +464,18 @@ crm_time_set_if_earlier(crm_time_t *next_change, crm_time_t *t)
 | |
|   * \return Standard Pacemaker return code
 | |
|   */
 | |
|  int
 | |
| -pe_eval_date_expression(xmlNode *time_expr, crm_time_t *now,
 | |
| -                        crm_time_t *next_change)
 | |
| +pe_eval_date_expression(xmlNode *expr, crm_time_t *now, crm_time_t *next_change)
 | |
|  {
 | |
| -    crm_time_t *start = NULL;
 | |
| -    crm_time_t *end = NULL;
 | |
| -    const char *value = NULL;
 | |
| -    const char *op = crm_element_value(time_expr, "operation");
 | |
| -
 | |
| -    xmlNode *duration_spec = NULL;
 | |
| -    xmlNode *date_spec = NULL;
 | |
| -
 | |
| -    // "undetermined" will also be returned for parsing errors
 | |
| -    int rc = pcmk_rc_undetermined;
 | |
| -
 | |
| -    crm_trace("Testing expression: %s", ID(time_expr));
 | |
| -
 | |
| -    duration_spec = first_named_child(time_expr, "duration");
 | |
| -    date_spec = first_named_child(time_expr, "date_spec");
 | |
| -
 | |
| -    value = crm_element_value(time_expr, "start");
 | |
| -    if (value != NULL) {
 | |
| -        start = crm_time_new(value);
 | |
| -    }
 | |
| -    value = crm_element_value(time_expr, "end");
 | |
| -    if (value != NULL) {
 | |
| -        end = crm_time_new(value);
 | |
| -    }
 | |
| -
 | |
| -    if (start != NULL && end == NULL && duration_spec != NULL) {
 | |
| -        end = pe_parse_xml_duration(start, duration_spec);
 | |
| -    }
 | |
| -
 | |
| -    if ((op == NULL) || safe_str_eq(op, "in_range")) {
 | |
| -        if ((start == NULL) && (end == NULL)) {
 | |
| -            // in_range requires at least one of start or end
 | |
| -        } else if ((start != NULL) && (crm_time_compare(now, start) < 0)) {
 | |
| -            rc = pcmk_rc_before_range;
 | |
| -            crm_time_set_if_earlier(next_change, start);
 | |
| -        } else if ((end != NULL) && (crm_time_compare(now, end) > 0)) {
 | |
| -            rc = pcmk_rc_after_range;
 | |
| -        } else {
 | |
| -            rc = pcmk_rc_within_range;
 | |
| -            if (end && next_change) {
 | |
| -                // Evaluation doesn't change until second after end
 | |
| -                crm_time_add_seconds(end, 1);
 | |
| -                crm_time_set_if_earlier(next_change, end);
 | |
| -            }
 | |
| -        }
 | |
| -
 | |
| -    } else if (safe_str_eq(op, "date_spec")) {
 | |
| -        rc = pe_cron_range_satisfied(now, date_spec);
 | |
| -        // @TODO set next_change appropriately
 | |
| -
 | |
| -    } else if (safe_str_eq(op, "gt")) {
 | |
| -        if (start == NULL) {
 | |
| -            // gt requires start
 | |
| -        } else if (crm_time_compare(now, start) > 0) {
 | |
| -            rc = pcmk_rc_within_range;
 | |
| -        } else {
 | |
| -            rc = pcmk_rc_before_range;
 | |
| -
 | |
| -            // Evaluation doesn't change until second after start
 | |
| -            crm_time_add_seconds(start, 1);
 | |
| -            crm_time_set_if_earlier(next_change, start);
 | |
| -        }
 | |
| -
 | |
| -    } else if (safe_str_eq(op, "lt")) {
 | |
| -        if (end == NULL) {
 | |
| -            // lt requires end
 | |
| -        } else if (crm_time_compare(now, end) < 0) {
 | |
| -            rc = pcmk_rc_within_range;
 | |
| -            crm_time_set_if_earlier(next_change, end);
 | |
| -        } else {
 | |
| -            rc = pcmk_rc_after_range;
 | |
| -        }
 | |
| -    }
 | |
| -
 | |
| -    crm_time_free(start);
 | |
| -    crm_time_free(end);
 | |
| -    return rc;
 | |
| +    pe_rule_eval_data_t rule_data = {
 | |
| +        .node_hash = NULL,
 | |
| +        .role = RSC_ROLE_UNKNOWN,
 | |
| +        .now = now,
 | |
| +        .match_data = NULL,
 | |
| +        .rsc_data = NULL,
 | |
| +        .op_data = NULL
 | |
| +    };
 | |
| +
 | |
| +    return pe__eval_date_expr(expr, &rule_data, next_change);
 | |
|  }
 | |
|  
 | |
|  // Information about a block of nvpair elements
 | |
| @@ -1111,6 +884,285 @@ pe_unpack_versioned_parameters(xmlNode *versioned_params, const char *ra_version
 | |
|  }
 | |
|  #endif
 | |
|  
 | |
| +gboolean
 | |
| +pe__eval_attr_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data)
 | |
| +{
 | |
| +    gboolean accept = FALSE;
 | |
| +    gboolean attr_allocated = FALSE;
 | |
| +    int cmp = 0;
 | |
| +    const char *h_val = NULL;
 | |
| +    GHashTable *table = NULL;
 | |
| +
 | |
| +    const char *op = NULL;
 | |
| +    const char *type = NULL;
 | |
| +    const char *attr = NULL;
 | |
| +    const char *value = NULL;
 | |
| +    const char *value_source = NULL;
 | |
| +
 | |
| +    attr = crm_element_value(expr, XML_EXPR_ATTR_ATTRIBUTE);
 | |
| +    op = crm_element_value(expr, XML_EXPR_ATTR_OPERATION);
 | |
| +    value = crm_element_value(expr, XML_EXPR_ATTR_VALUE);
 | |
| +    type = crm_element_value(expr, XML_EXPR_ATTR_TYPE);
 | |
| +    value_source = crm_element_value(expr, XML_EXPR_ATTR_VALUE_SOURCE);
 | |
| +
 | |
| +    if (attr == NULL || op == NULL) {
 | |
| +        pe_err("Invalid attribute or operation in expression"
 | |
| +               " (\'%s\' \'%s\' \'%s\')", crm_str(attr), crm_str(op), crm_str(value));
 | |
| +        return FALSE;
 | |
| +    }
 | |
| +
 | |
| +    if (rule_data->match_data) {
 | |
| +        if (rule_data->match_data->re) {
 | |
| +            char *resolved_attr = pe_expand_re_matches(attr, rule_data->match_data->re);
 | |
| +
 | |
| +            if (resolved_attr) {
 | |
| +                attr = (const char *) resolved_attr;
 | |
| +                attr_allocated = TRUE;
 | |
| +            }
 | |
| +        }
 | |
| +
 | |
| +        if (safe_str_eq(value_source, "param")) {
 | |
| +            table = rule_data->match_data->params;
 | |
| +        } else if (safe_str_eq(value_source, "meta")) {
 | |
| +            table = rule_data->match_data->meta;
 | |
| +        }
 | |
| +    }
 | |
| +
 | |
| +    if (table) {
 | |
| +        const char *param_name = value;
 | |
| +        const char *param_value = NULL;
 | |
| +
 | |
| +        if (param_name && param_name[0]) {
 | |
| +            if ((param_value = (const char *)g_hash_table_lookup(table, param_name))) {
 | |
| +                value = param_value;
 | |
| +            }
 | |
| +        }
 | |
| +    }
 | |
| +
 | |
| +    if (rule_data->node_hash != NULL) {
 | |
| +        h_val = (const char *)g_hash_table_lookup(rule_data->node_hash, attr);
 | |
| +    }
 | |
| +
 | |
| +    if (attr_allocated) {
 | |
| +        free((char *)attr);
 | |
| +        attr = NULL;
 | |
| +    }
 | |
| +
 | |
| +    if (value != NULL && h_val != NULL) {
 | |
| +        if (type == NULL) {
 | |
| +            if (safe_str_eq(op, "lt")
 | |
| +                || safe_str_eq(op, "lte")
 | |
| +                || safe_str_eq(op, "gt")
 | |
| +                || safe_str_eq(op, "gte")) {
 | |
| +                type = "number";
 | |
| +
 | |
| +            } else {
 | |
| +                type = "string";
 | |
| +            }
 | |
| +            crm_trace("Defaulting to %s based comparison for '%s' op", type, op);
 | |
| +        }
 | |
| +
 | |
| +        if (safe_str_eq(type, "string")) {
 | |
| +            cmp = strcasecmp(h_val, value);
 | |
| +
 | |
| +        } else if (safe_str_eq(type, "number")) {
 | |
| +            int h_val_f = crm_parse_int(h_val, NULL);
 | |
| +            int value_f = crm_parse_int(value, NULL);
 | |
| +
 | |
| +            if (h_val_f < value_f) {
 | |
| +                cmp = -1;
 | |
| +            } else if (h_val_f > value_f) {
 | |
| +                cmp = 1;
 | |
| +            } else {
 | |
| +                cmp = 0;
 | |
| +            }
 | |
| +
 | |
| +        } else if (safe_str_eq(type, "version")) {
 | |
| +            cmp = compare_version(h_val, value);
 | |
| +
 | |
| +        }
 | |
| +
 | |
| +    } else if (value == NULL && h_val == NULL) {
 | |
| +        cmp = 0;
 | |
| +    } else if (value == NULL) {
 | |
| +        cmp = 1;
 | |
| +    } else {
 | |
| +        cmp = -1;
 | |
| +    }
 | |
| +
 | |
| +    if (safe_str_eq(op, "defined")) {
 | |
| +        if (h_val != NULL) {
 | |
| +            accept = TRUE;
 | |
| +        }
 | |
| +
 | |
| +    } else if (safe_str_eq(op, "not_defined")) {
 | |
| +        if (h_val == NULL) {
 | |
| +            accept = TRUE;
 | |
| +        }
 | |
| +
 | |
| +    } else if (safe_str_eq(op, "eq")) {
 | |
| +        if ((h_val == value) || cmp == 0) {
 | |
| +            accept = TRUE;
 | |
| +        }
 | |
| +
 | |
| +    } else if (safe_str_eq(op, "ne")) {
 | |
| +        if ((h_val == NULL && value != NULL)
 | |
| +            || (h_val != NULL && value == NULL)
 | |
| +            || cmp != 0) {
 | |
| +            accept = TRUE;
 | |
| +        }
 | |
| +
 | |
| +    } else if (value == NULL || h_val == NULL) {
 | |
| +        // The comparison is meaningless from this point on
 | |
| +        accept = FALSE;
 | |
| +
 | |
| +    } else if (safe_str_eq(op, "lt")) {
 | |
| +        if (cmp < 0) {
 | |
| +            accept = TRUE;
 | |
| +        }
 | |
| +
 | |
| +    } else if (safe_str_eq(op, "lte")) {
 | |
| +        if (cmp <= 0) {
 | |
| +            accept = TRUE;
 | |
| +        }
 | |
| +
 | |
| +    } else if (safe_str_eq(op, "gt")) {
 | |
| +        if (cmp > 0) {
 | |
| +            accept = TRUE;
 | |
| +        }
 | |
| +
 | |
| +    } else if (safe_str_eq(op, "gte")) {
 | |
| +        if (cmp >= 0) {
 | |
| +            accept = TRUE;
 | |
| +        }
 | |
| +    }
 | |
| +
 | |
| +    return accept;
 | |
| +}
 | |
| +
 | |
| +int
 | |
| +pe__eval_date_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data, crm_time_t *next_change)
 | |
| +{
 | |
| +    crm_time_t *start = NULL;
 | |
| +    crm_time_t *end = NULL;
 | |
| +    const char *value = NULL;
 | |
| +    const char *op = crm_element_value(expr, "operation");
 | |
| +
 | |
| +    xmlNode *duration_spec = NULL;
 | |
| +    xmlNode *date_spec = NULL;
 | |
| +
 | |
| +    // "undetermined" will also be returned for parsing errors
 | |
| +    int rc = pcmk_rc_undetermined;
 | |
| +
 | |
| +    crm_trace("Testing expression: %s", ID(expr));
 | |
| +
 | |
| +    duration_spec = first_named_child(expr, "duration");
 | |
| +    date_spec = first_named_child(expr, "date_spec");
 | |
| +
 | |
| +    value = crm_element_value(expr, "start");
 | |
| +    if (value != NULL) {
 | |
| +        start = crm_time_new(value);
 | |
| +    }
 | |
| +    value = crm_element_value(expr, "end");
 | |
| +    if (value != NULL) {
 | |
| +        end = crm_time_new(value);
 | |
| +    }
 | |
| +
 | |
| +    if (start != NULL && end == NULL && duration_spec != NULL) {
 | |
| +        end = pe_parse_xml_duration(start, duration_spec);
 | |
| +    }
 | |
| +
 | |
| +    if ((op == NULL) || safe_str_eq(op, "in_range")) {
 | |
| +        if ((start == NULL) && (end == NULL)) {
 | |
| +            // in_range requires at least one of start or end
 | |
| +        } else if ((start != NULL) && (crm_time_compare(rule_data->now, start) < 0)) {
 | |
| +            rc = pcmk_rc_before_range;
 | |
| +            crm_time_set_if_earlier(next_change, start);
 | |
| +        } else if ((end != NULL) && (crm_time_compare(rule_data->now, end) > 0)) {
 | |
| +            rc = pcmk_rc_after_range;
 | |
| +        } else {
 | |
| +            rc = pcmk_rc_within_range;
 | |
| +            if (end && next_change) {
 | |
| +                // Evaluation doesn't change until second after end
 | |
| +                crm_time_add_seconds(end, 1);
 | |
| +                crm_time_set_if_earlier(next_change, end);
 | |
| +            }
 | |
| +        }
 | |
| +
 | |
| +    } else if (safe_str_eq(op, "date_spec")) {
 | |
| +        rc = pe_cron_range_satisfied(rule_data->now, date_spec);
 | |
| +        // @TODO set next_change appropriately
 | |
| +
 | |
| +    } else if (safe_str_eq(op, "gt")) {
 | |
| +        if (start == NULL) {
 | |
| +            // gt requires start
 | |
| +        } else if (crm_time_compare(rule_data->now, start) > 0) {
 | |
| +            rc = pcmk_rc_within_range;
 | |
| +        } else {
 | |
| +            rc = pcmk_rc_before_range;
 | |
| +
 | |
| +            // Evaluation doesn't change until second after start
 | |
| +            crm_time_add_seconds(start, 1);
 | |
| +            crm_time_set_if_earlier(next_change, start);
 | |
| +        }
 | |
| +
 | |
| +    } else if (safe_str_eq(op, "lt")) {
 | |
| +        if (end == NULL) {
 | |
| +            // lt requires end
 | |
| +        } else if (crm_time_compare(rule_data->now, end) < 0) {
 | |
| +            rc = pcmk_rc_within_range;
 | |
| +            crm_time_set_if_earlier(next_change, end);
 | |
| +        } else {
 | |
| +            rc = pcmk_rc_after_range;
 | |
| +        }
 | |
| +    }
 | |
| +
 | |
| +    crm_time_free(start);
 | |
| +    crm_time_free(end);
 | |
| +    return rc;
 | |
| +}
 | |
| +
 | |
| +gboolean
 | |
| +pe__eval_role_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data)
 | |
| +{
 | |
| +    gboolean accept = FALSE;
 | |
| +    const char *op = NULL;
 | |
| +    const char *value = NULL;
 | |
| +
 | |
| +    if (rule_data->role == RSC_ROLE_UNKNOWN) {
 | |
| +        return accept;
 | |
| +    }
 | |
| +
 | |
| +    value = crm_element_value(expr, XML_EXPR_ATTR_VALUE);
 | |
| +    op = crm_element_value(expr, XML_EXPR_ATTR_OPERATION);
 | |
| +
 | |
| +    if (safe_str_eq(op, "defined")) {
 | |
| +        if (rule_data->role > RSC_ROLE_STARTED) {
 | |
| +            accept = TRUE;
 | |
| +        }
 | |
| +
 | |
| +    } else if (safe_str_eq(op, "not_defined")) {
 | |
| +        if (rule_data->role < RSC_ROLE_SLAVE && rule_data->role > RSC_ROLE_UNKNOWN) {
 | |
| +            accept = TRUE;
 | |
| +        }
 | |
| +
 | |
| +    } else if (safe_str_eq(op, "eq")) {
 | |
| +        if (text2role(value) == rule_data->role) {
 | |
| +            accept = TRUE;
 | |
| +        }
 | |
| +
 | |
| +    } else if (safe_str_eq(op, "ne")) {
 | |
| +        // Test "ne" only with promotable clone roles
 | |
| +        if (rule_data->role < RSC_ROLE_SLAVE && rule_data->role > RSC_ROLE_UNKNOWN) {
 | |
| +            accept = FALSE;
 | |
| +
 | |
| +        } else if (text2role(value) != rule_data->role) {
 | |
| +            accept = TRUE;
 | |
| +        }
 | |
| +    }
 | |
| +    return accept;
 | |
| +}
 | |
| +
 | |
|  // Deprecated functions kept only for backward API compatibility
 | |
|  gboolean test_ruleset(xmlNode *ruleset, GHashTable *node_hash, crm_time_t *now);
 | |
|  gboolean test_rule(xmlNode *rule, GHashTable *node_hash, enum rsc_role_e role,
 | |
| -- 
 | |
| 1.8.3.1
 | |
| 
 | |
| 
 | |
| From 56a1337a54f3ba8a175ff3252658e1e43f7c670b Mon Sep 17 00:00:00 2001
 | |
| From: Chris Lumens <clumens@redhat.com>
 | |
| Date: Tue, 28 Apr 2020 14:34:40 -0400
 | |
| Subject: [PATCH 03/17] Feature: scheduler: Add new rule tests for op_defaults
 | |
|  and rsc_defaults.
 | |
| 
 | |
| These are like all the other rule evaluating functions, but they do not
 | |
| have any wrappers for the older style API.
 | |
| ---
 | |
|  include/crm/pengine/rules_internal.h |  2 ++
 | |
|  lib/pengine/rules.c                  | 68 ++++++++++++++++++++++++++++++++++++
 | |
|  2 files changed, 70 insertions(+)
 | |
| 
 | |
| diff --git a/include/crm/pengine/rules_internal.h b/include/crm/pengine/rules_internal.h
 | |
| index 8a22108..f60263a 100644
 | |
| --- a/include/crm/pengine/rules_internal.h
 | |
| +++ b/include/crm/pengine/rules_internal.h
 | |
| @@ -24,7 +24,9 @@ crm_time_t *pe_parse_xml_duration(crm_time_t * start, xmlNode * duration_spec);
 | |
|  gboolean pe__eval_attr_expr(xmlNode *expr, pe_rule_eval_data_t *rule_data);
 | |
|  int pe__eval_date_expr(xmlNode *expr, pe_rule_eval_data_t *rule_data,
 | |
|                         crm_time_t *next_change);
 | |
| +gboolean pe__eval_op_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data);
 | |
|  gboolean pe__eval_role_expr(xmlNode *expr, pe_rule_eval_data_t *rule_data);
 | |
| +gboolean pe__eval_rsc_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data);
 | |
|  
 | |
|  int pe_eval_date_expression(xmlNode *time_expr,
 | |
|                              crm_time_t *now,
 | |
| diff --git a/lib/pengine/rules.c b/lib/pengine/rules.c
 | |
| index 3f316c2..a5af57a 100644
 | |
| --- a/lib/pengine/rules.c
 | |
| +++ b/lib/pengine/rules.c
 | |
| @@ -1123,6 +1123,38 @@ pe__eval_date_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data, crm_time_t *
 | |
|  }
 | |
|  
 | |
|  gboolean
 | |
| +pe__eval_op_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data) {
 | |
| +    const char *name = crm_element_value(expr, XML_NVPAIR_ATTR_NAME);
 | |
| +    const char *interval_s = crm_element_value(expr, XML_LRM_ATTR_INTERVAL);
 | |
| +    guint interval;
 | |
| +
 | |
| +    crm_trace("Testing op_defaults expression: %s", ID(expr));
 | |
| +
 | |
| +    if (rule_data->op_data == NULL) {
 | |
| +        crm_trace("No operations data provided");
 | |
| +        return FALSE;
 | |
| +    }
 | |
| +
 | |
| +    interval = crm_parse_interval_spec(interval_s);
 | |
| +    if (interval == 0 && errno != 0) {
 | |
| +        crm_trace("Could not parse interval: %s", interval_s);
 | |
| +        return FALSE;
 | |
| +    }
 | |
| +
 | |
| +    if (interval_s != NULL && interval != rule_data->op_data->interval) {
 | |
| +        crm_trace("Interval doesn't match: %d != %d", interval, rule_data->op_data->interval);
 | |
| +        return FALSE;
 | |
| +    }
 | |
| +
 | |
| +    if (!crm_str_eq(name, rule_data->op_data->op_name, TRUE)) {
 | |
| +        crm_trace("Name doesn't match: %s != %s", name, rule_data->op_data->op_name);
 | |
| +        return FALSE;
 | |
| +    }
 | |
| +
 | |
| +    return TRUE;
 | |
| +}
 | |
| +
 | |
| +gboolean
 | |
|  pe__eval_role_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data)
 | |
|  {
 | |
|      gboolean accept = FALSE;
 | |
| @@ -1163,6 +1195,42 @@ pe__eval_role_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data)
 | |
|      return accept;
 | |
|  }
 | |
|  
 | |
| +gboolean
 | |
| +pe__eval_rsc_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data)
 | |
| +{
 | |
| +    const char *class = crm_element_value(expr, XML_AGENT_ATTR_CLASS);
 | |
| +    const char *provider = crm_element_value(expr, XML_AGENT_ATTR_PROVIDER);
 | |
| +    const char *type = crm_element_value(expr, XML_EXPR_ATTR_TYPE);
 | |
| +
 | |
| +    crm_trace("Testing rsc_defaults expression: %s", ID(expr));
 | |
| +
 | |
| +    if (rule_data->rsc_data == NULL) {
 | |
| +        crm_trace("No resource data provided");
 | |
| +        return FALSE;
 | |
| +    }
 | |
| +
 | |
| +    if (class != NULL &&
 | |
| +        !crm_str_eq(class, rule_data->rsc_data->standard, TRUE)) {
 | |
| +        crm_trace("Class doesn't match: %s != %s", class, rule_data->rsc_data->standard);
 | |
| +        return FALSE;
 | |
| +    }
 | |
| +
 | |
| +    if ((provider == NULL && rule_data->rsc_data->provider != NULL) ||
 | |
| +        (provider != NULL && rule_data->rsc_data->provider == NULL) ||
 | |
| +        !crm_str_eq(provider, rule_data->rsc_data->provider, TRUE)) {
 | |
| +        crm_trace("Provider doesn't match: %s != %s", provider, rule_data->rsc_data->provider);
 | |
| +        return FALSE;
 | |
| +    }
 | |
| +
 | |
| +    if (type != NULL &&
 | |
| +        !crm_str_eq(type, rule_data->rsc_data->agent, TRUE)) {
 | |
| +        crm_trace("Agent doesn't match: %s != %s", type, rule_data->rsc_data->agent);
 | |
| +        return FALSE;
 | |
| +    }
 | |
| +
 | |
| +    return TRUE;
 | |
| +}
 | |
| +
 | |
|  // Deprecated functions kept only for backward API compatibility
 | |
|  gboolean test_ruleset(xmlNode *ruleset, GHashTable *node_hash, crm_time_t *now);
 | |
|  gboolean test_rule(xmlNode *rule, GHashTable *node_hash, enum rsc_role_e role,
 | |
| -- 
 | |
| 1.8.3.1
 | |
| 
 | |
| 
 | |
| From 5a4da3f77feee0d3bac50e9adc4eb4b35724dfb2 Mon Sep 17 00:00:00 2001
 | |
| From: Chris Lumens <clumens@redhat.com>
 | |
| Date: Tue, 28 Apr 2020 14:41:08 -0400
 | |
| Subject: [PATCH 04/17] Refactor: scheduler: Reimplement core rule eval
 | |
|  functions.
 | |
| 
 | |
| The core functions of pe_evaluate_rules, pe_test_rule, and
 | |
| pe_test_expression have been turned into new, similarly named functions
 | |
| that take a pe_rule_eval_data_t as an argument.  The old ones still
 | |
| exist as wrappers around the new ones.
 | |
| ---
 | |
|  include/crm/pengine/rules.h |   7 ++
 | |
|  lib/pengine/rules.c         | 259 ++++++++++++++++++++++++++------------------
 | |
|  2 files changed, 162 insertions(+), 104 deletions(-)
 | |
| 
 | |
| diff --git a/include/crm/pengine/rules.h b/include/crm/pengine/rules.h
 | |
| index d7bdbf9..a74c629 100644
 | |
| --- a/include/crm/pengine/rules.h
 | |
| +++ b/include/crm/pengine/rules.h
 | |
| @@ -61,6 +61,13 @@ GHashTable *pe_unpack_versioned_parameters(xmlNode *versioned_params, const char
 | |
|  
 | |
|  char *pe_expand_re_matches(const char *string, pe_re_match_data_t * match_data);
 | |
|  
 | |
| +gboolean pe_eval_rules(xmlNode *ruleset, pe_rule_eval_data_t *rule_data,
 | |
| +                       crm_time_t *next_change);
 | |
| +gboolean pe_eval_expr(xmlNode *rule, pe_rule_eval_data_t *rule_data,
 | |
| +                      crm_time_t *next_change);
 | |
| +gboolean pe_eval_subexpr(xmlNode *expr, pe_rule_eval_data_t *rule_data,
 | |
| +                         crm_time_t *next_change);
 | |
| +
 | |
|  #ifndef PCMK__NO_COMPAT
 | |
|  /* Everything here is deprecated and kept only for public API backward
 | |
|   * compatibility. It will be moved to compatibility.h when 2.1.0 is released.
 | |
| diff --git a/lib/pengine/rules.c b/lib/pengine/rules.c
 | |
| index a5af57a..a6353ef 100644
 | |
| --- a/lib/pengine/rules.c
 | |
| +++ b/lib/pengine/rules.c
 | |
| @@ -38,25 +38,16 @@ gboolean
 | |
|  pe_evaluate_rules(xmlNode *ruleset, GHashTable *node_hash, crm_time_t *now,
 | |
|                    crm_time_t *next_change)
 | |
|  {
 | |
| -    // If there are no rules, pass by default
 | |
| -    gboolean ruleset_default = TRUE;
 | |
| -
 | |
| -    for (xmlNode *rule = first_named_child(ruleset, XML_TAG_RULE);
 | |
| -         rule != NULL; rule = crm_next_same_xml(rule)) {
 | |
| +    pe_rule_eval_data_t rule_data = {
 | |
| +        .node_hash = node_hash,
 | |
| +        .role = RSC_ROLE_UNKNOWN,
 | |
| +        .now = now,
 | |
| +        .match_data = NULL,
 | |
| +        .rsc_data = NULL,
 | |
| +        .op_data = NULL
 | |
| +    };
 | |
|  
 | |
| -        ruleset_default = FALSE;
 | |
| -        if (pe_test_rule(rule, node_hash, RSC_ROLE_UNKNOWN, now, next_change,
 | |
| -                         NULL)) {
 | |
| -            /* Only the deprecated "lifetime" element of location constraints
 | |
| -             * may contain more than one rule at the top level -- the schema
 | |
| -             * limits a block of nvpairs to a single top-level rule. So, this
 | |
| -             * effectively means that a lifetime is active if any rule it
 | |
| -             * contains is active.
 | |
| -             */
 | |
| -            return TRUE;
 | |
| -        }
 | |
| -    }
 | |
| -    return ruleset_default;
 | |
| +    return pe_eval_rules(ruleset, &rule_data, next_change);
 | |
|  }
 | |
|  
 | |
|  gboolean
 | |
| @@ -64,44 +55,16 @@ pe_test_rule(xmlNode *rule, GHashTable *node_hash, enum rsc_role_e role,
 | |
|               crm_time_t *now, crm_time_t *next_change,
 | |
|               pe_match_data_t *match_data)
 | |
|  {
 | |
| -    xmlNode *expr = NULL;
 | |
| -    gboolean test = TRUE;
 | |
| -    gboolean empty = TRUE;
 | |
| -    gboolean passed = TRUE;
 | |
| -    gboolean do_and = TRUE;
 | |
| -    const char *value = NULL;
 | |
| -
 | |
| -    rule = expand_idref(rule, NULL);
 | |
| -    value = crm_element_value(rule, XML_RULE_ATTR_BOOLEAN_OP);
 | |
| -    if (safe_str_eq(value, "or")) {
 | |
| -        do_and = FALSE;
 | |
| -        passed = FALSE;
 | |
| -    }
 | |
| -
 | |
| -    crm_trace("Testing rule %s", ID(rule));
 | |
| -    for (expr = __xml_first_child_element(rule); expr != NULL;
 | |
| -         expr = __xml_next_element(expr)) {
 | |
| -
 | |
| -        test = pe_test_expression(expr, node_hash, role, now, next_change,
 | |
| -                                  match_data);
 | |
| -        empty = FALSE;
 | |
| -
 | |
| -        if (test && do_and == FALSE) {
 | |
| -            crm_trace("Expression %s/%s passed", ID(rule), ID(expr));
 | |
| -            return TRUE;
 | |
| -
 | |
| -        } else if (test == FALSE && do_and) {
 | |
| -            crm_trace("Expression %s/%s failed", ID(rule), ID(expr));
 | |
| -            return FALSE;
 | |
| -        }
 | |
| -    }
 | |
| -
 | |
| -    if (empty) {
 | |
| -        crm_err("Invalid Rule %s: rules must contain at least one expression", ID(rule));
 | |
| -    }
 | |
| +    pe_rule_eval_data_t rule_data = {
 | |
| +        .node_hash = node_hash,
 | |
| +        .role = role,
 | |
| +        .now = now,
 | |
| +        .match_data = match_data,
 | |
| +        .rsc_data = NULL,
 | |
| +        .op_data = NULL
 | |
| +    };
 | |
|  
 | |
| -    crm_trace("Rule %s %s", ID(rule), passed ? "passed" : "failed");
 | |
| -    return passed;
 | |
| +    return pe_eval_expr(rule, &rule_data, next_change);
 | |
|  }
 | |
|  
 | |
|  /*!
 | |
| @@ -125,56 +88,16 @@ pe_test_expression(xmlNode *expr, GHashTable *node_hash, enum rsc_role_e role,
 | |
|                     crm_time_t *now, crm_time_t *next_change,
 | |
|                     pe_match_data_t *match_data)
 | |
|  {
 | |
| -    gboolean accept = FALSE;
 | |
| -    const char *uname = NULL;
 | |
| -
 | |
| -    switch (find_expression_type(expr)) {
 | |
| -        case nested_rule:
 | |
| -            accept = pe_test_rule(expr, node_hash, role, now, next_change,
 | |
| -                                  match_data);
 | |
| -            break;
 | |
| -        case attr_expr:
 | |
| -        case loc_expr:
 | |
| -            /* these expressions can never succeed if there is
 | |
| -             * no node to compare with
 | |
| -             */
 | |
| -            if (node_hash != NULL) {
 | |
| -                accept = pe_test_attr_expression(expr, node_hash, now, match_data);
 | |
| -            }
 | |
| -            break;
 | |
| -
 | |
| -        case time_expr:
 | |
| -            accept = pe_test_date_expression(expr, now, next_change);
 | |
| -            break;
 | |
| -
 | |
| -        case role_expr:
 | |
| -            accept = pe_test_role_expression(expr, role, now);
 | |
| -            break;
 | |
| -
 | |
| -#if ENABLE_VERSIONED_ATTRS
 | |
| -        case version_expr:
 | |
| -            if (node_hash && g_hash_table_lookup_extended(node_hash,
 | |
| -                                                          CRM_ATTR_RA_VERSION,
 | |
| -                                                          NULL, NULL)) {
 | |
| -                accept = pe_test_attr_expression(expr, node_hash, now, NULL);
 | |
| -            } else {
 | |
| -                // we are going to test it when we have ra-version
 | |
| -                accept = TRUE;
 | |
| -            }
 | |
| -            break;
 | |
| -#endif
 | |
| -
 | |
| -        default:
 | |
| -            CRM_CHECK(FALSE /* bad type */ , return FALSE);
 | |
| -            accept = FALSE;
 | |
| -    }
 | |
| -    if (node_hash) {
 | |
| -        uname = g_hash_table_lookup(node_hash, CRM_ATTR_UNAME);
 | |
| -    }
 | |
| +    pe_rule_eval_data_t rule_data = {
 | |
| +        .node_hash = node_hash,
 | |
| +        .role = role,
 | |
| +        .now = now,
 | |
| +        .match_data = match_data,
 | |
| +        .rsc_data = NULL,
 | |
| +        .op_data = NULL
 | |
| +    };
 | |
|  
 | |
| -    crm_trace("Expression %s %s on %s",
 | |
| -              ID(expr), accept ? "passed" : "failed", uname ? uname : "all nodes");
 | |
| -    return accept;
 | |
| +    return pe_eval_subexpr(expr, &rule_data, next_change);
 | |
|  }
 | |
|  
 | |
|  enum expression_type
 | |
| @@ -885,6 +808,134 @@ pe_unpack_versioned_parameters(xmlNode *versioned_params, const char *ra_version
 | |
|  #endif
 | |
|  
 | |
|  gboolean
 | |
| +pe_eval_rules(xmlNode *ruleset, pe_rule_eval_data_t *rule_data, crm_time_t *next_change)
 | |
| +{
 | |
| +    // If there are no rules, pass by default
 | |
| +    gboolean ruleset_default = TRUE;
 | |
| +
 | |
| +    for (xmlNode *rule = first_named_child(ruleset, XML_TAG_RULE);
 | |
| +         rule != NULL; rule = crm_next_same_xml(rule)) {
 | |
| +
 | |
| +        ruleset_default = FALSE;
 | |
| +        if (pe_eval_expr(rule, rule_data, next_change)) {
 | |
| +            /* Only the deprecated "lifetime" element of location constraints
 | |
| +             * may contain more than one rule at the top level -- the schema
 | |
| +             * limits a block of nvpairs to a single top-level rule. So, this
 | |
| +             * effectively means that a lifetime is active if any rule it
 | |
| +             * contains is active.
 | |
| +             */
 | |
| +            return TRUE;
 | |
| +        }
 | |
| +    }
 | |
| +
 | |
| +    return ruleset_default;
 | |
| +}
 | |
| +
 | |
| +gboolean
 | |
| +pe_eval_expr(xmlNode *rule, pe_rule_eval_data_t *rule_data, crm_time_t *next_change)
 | |
| +{
 | |
| +    xmlNode *expr = NULL;
 | |
| +    gboolean test = TRUE;
 | |
| +    gboolean empty = TRUE;
 | |
| +    gboolean passed = TRUE;
 | |
| +    gboolean do_and = TRUE;
 | |
| +    const char *value = NULL;
 | |
| +
 | |
| +    rule = expand_idref(rule, NULL);
 | |
| +    value = crm_element_value(rule, XML_RULE_ATTR_BOOLEAN_OP);
 | |
| +    if (safe_str_eq(value, "or")) {
 | |
| +        do_and = FALSE;
 | |
| +        passed = FALSE;
 | |
| +    }
 | |
| +
 | |
| +    crm_trace("Testing rule %s", ID(rule));
 | |
| +    for (expr = __xml_first_child_element(rule); expr != NULL;
 | |
| +         expr = __xml_next_element(expr)) {
 | |
| +
 | |
| +        test = pe_eval_subexpr(expr, rule_data, next_change);
 | |
| +        empty = FALSE;
 | |
| +
 | |
| +        if (test && do_and == FALSE) {
 | |
| +            crm_trace("Expression %s/%s passed", ID(rule), ID(expr));
 | |
| +            return TRUE;
 | |
| +
 | |
| +        } else if (test == FALSE && do_and) {
 | |
| +            crm_trace("Expression %s/%s failed", ID(rule), ID(expr));
 | |
| +            return FALSE;
 | |
| +        }
 | |
| +    }
 | |
| +
 | |
| +    if (empty) {
 | |
| +        crm_err("Invalid Rule %s: rules must contain at least one expression", ID(rule));
 | |
| +    }
 | |
| +
 | |
| +    crm_trace("Rule %s %s", ID(rule), passed ? "passed" : "failed");
 | |
| +    return passed;
 | |
| +}
 | |
| +
 | |
| +gboolean
 | |
| +pe_eval_subexpr(xmlNode *expr, pe_rule_eval_data_t *rule_data, crm_time_t *next_change)
 | |
| +{
 | |
| +    gboolean accept = FALSE;
 | |
| +    const char *uname = NULL;
 | |
| +
 | |
| +    switch (find_expression_type(expr)) {
 | |
| +        case nested_rule:
 | |
| +            accept = pe_eval_expr(expr, rule_data, next_change);
 | |
| +            break;
 | |
| +        case attr_expr:
 | |
| +        case loc_expr:
 | |
| +            /* these expressions can never succeed if there is
 | |
| +             * no node to compare with
 | |
| +             */
 | |
| +            if (rule_data->node_hash != NULL) {
 | |
| +                accept = pe__eval_attr_expr(expr, rule_data);
 | |
| +            }
 | |
| +            break;
 | |
| +
 | |
| +        case time_expr:
 | |
| +            accept = pe_test_date_expression(expr, rule_data->now, next_change);
 | |
| +            break;
 | |
| +
 | |
| +        case role_expr:
 | |
| +            accept = pe__eval_role_expr(expr, rule_data);
 | |
| +            break;
 | |
| +
 | |
| +        case rsc_expr:
 | |
| +            accept = pe__eval_rsc_expr(expr, rule_data);
 | |
| +            break;
 | |
| +
 | |
| +        case op_expr:
 | |
| +            accept = pe__eval_op_expr(expr, rule_data);
 | |
| +            break;
 | |
| +
 | |
| +#if ENABLE_VERSIONED_ATTRS
 | |
| +        case version_expr:
 | |
| +            if (rule_data->node_hash &&
 | |
| +                g_hash_table_lookup_extended(rule_data->node_hash,
 | |
| +                                             CRM_ATTR_RA_VERSION, NULL, NULL)) {
 | |
| +                accept = pe__eval_attr_expr(expr, rule_data);
 | |
| +            } else {
 | |
| +                // we are going to test it when we have ra-version
 | |
| +                accept = TRUE;
 | |
| +            }
 | |
| +            break;
 | |
| +#endif
 | |
| +
 | |
| +        default:
 | |
| +            CRM_CHECK(FALSE /* bad type */ , return FALSE);
 | |
| +            accept = FALSE;
 | |
| +    }
 | |
| +    if (rule_data->node_hash) {
 | |
| +        uname = g_hash_table_lookup(rule_data->node_hash, CRM_ATTR_UNAME);
 | |
| +    }
 | |
| +
 | |
| +    crm_trace("Expression %s %s on %s",
 | |
| +              ID(expr), accept ? "passed" : "failed", uname ? uname : "all nodes");
 | |
| +    return accept;
 | |
| +}
 | |
| +
 | |
| +gboolean
 | |
|  pe__eval_attr_expr(xmlNodePtr expr, pe_rule_eval_data_t *rule_data)
 | |
|  {
 | |
|      gboolean accept = FALSE;
 | |
| -- 
 | |
| 1.8.3.1
 | |
| 
 | |
| 
 | |
| From ea6318252164578fd27dcef657e80f5225337a4b Mon Sep 17 00:00:00 2001
 | |
| From: Chris Lumens <clumens@redhat.com>
 | |
| Date: Tue, 7 Apr 2020 15:57:06 -0400
 | |
| Subject: [PATCH 05/17] Refactor: scheduler: Add rule_data to unpack_data_s.
 | |
| 
 | |
| This is just to get rid of a couple extra arguments to some internal
 | |
| functions and make them look like the external functions.
 | |
| ---
 | |
|  lib/pengine/rules.c | 65 ++++++++++++++++++++++++++++++++++++-----------------
 | |
|  1 file changed, 44 insertions(+), 21 deletions(-)
 | |
| 
 | |
| diff --git a/lib/pengine/rules.c b/lib/pengine/rules.c
 | |
| index a6353ef..2709d68 100644
 | |
| --- a/lib/pengine/rules.c
 | |
| +++ b/lib/pengine/rules.c
 | |
| @@ -555,10 +555,9 @@ add_versioned_attributes(xmlNode * attr_set, xmlNode * versioned_attrs)
 | |
|  
 | |
|  typedef struct unpack_data_s {
 | |
|      gboolean overwrite;
 | |
| -    GHashTable *node_hash;
 | |
|      void *hash;
 | |
| -    crm_time_t *now;
 | |
|      crm_time_t *next_change;
 | |
| +    pe_rule_eval_data_t *rule_data;
 | |
|      xmlNode *top;
 | |
|  } unpack_data_t;
 | |
|  
 | |
| @@ -568,14 +567,14 @@ unpack_attr_set(gpointer data, gpointer user_data)
 | |
|      sorted_set_t *pair = data;
 | |
|      unpack_data_t *unpack_data = user_data;
 | |
|  
 | |
| -    if (!pe_evaluate_rules(pair->attr_set, unpack_data->node_hash,
 | |
| -                           unpack_data->now, unpack_data->next_change)) {
 | |
| +    if (!pe_eval_rules(pair->attr_set, unpack_data->rule_data,
 | |
| +                       unpack_data->next_change)) {
 | |
|          return;
 | |
|      }
 | |
|  
 | |
|  #if ENABLE_VERSIONED_ATTRS
 | |
| -    if (get_versioned_rule(pair->attr_set) && !(unpack_data->node_hash &&
 | |
| -        g_hash_table_lookup_extended(unpack_data->node_hash,
 | |
| +    if (get_versioned_rule(pair->attr_set) && !(unpack_data->rule_data->node_hash &&
 | |
| +        g_hash_table_lookup_extended(unpack_data->rule_data->node_hash,
 | |
|                                       CRM_ATTR_RA_VERSION, NULL, NULL))) {
 | |
|          // we haven't actually tested versioned expressions yet
 | |
|          return;
 | |
| @@ -593,8 +592,8 @@ unpack_versioned_attr_set(gpointer data, gpointer user_data)
 | |
|      sorted_set_t *pair = data;
 | |
|      unpack_data_t *unpack_data = user_data;
 | |
|  
 | |
| -    if (pe_evaluate_rules(pair->attr_set, unpack_data->node_hash,
 | |
| -                          unpack_data->now, unpack_data->next_change)) {
 | |
| +    if (pe_eval_rules(pair->attr_set, unpack_data->rule_data,
 | |
| +                      unpack_data->next_change)) {
 | |
|          add_versioned_attributes(pair->attr_set, unpack_data->hash);
 | |
|      }
 | |
|  }
 | |
| @@ -658,19 +657,17 @@ make_pairs(xmlNode *top, xmlNode *xml_obj, const char *set_name,
 | |
|   * \param[in]  top           XML document root (used to expand id-ref's)
 | |
|   * \param[in]  xml_obj       XML element containing blocks of nvpair elements
 | |
|   * \param[in]  set_name      If not NULL, only use blocks of this element type
 | |
| - * \param[in]  node_hash     Node attributes to use when evaluating rules
 | |
|   * \param[out] hash          Where to store extracted name/value pairs
 | |
|   * \param[in]  always_first  If not NULL, process block with this ID first
 | |
|   * \param[in]  overwrite     Whether to replace existing values with same name
 | |
| - * \param[in]  now           Time to use when evaluating rules
 | |
| + * \param[in]  rule_data     Matching parameters to use when unpacking
 | |
|   * \param[out] next_change   If not NULL, set to when rule evaluation will change
 | |
|   * \param[in]  unpack_func   Function to call to unpack each block
 | |
|   */
 | |
|  static void
 | |
|  unpack_nvpair_blocks(xmlNode *top, xmlNode *xml_obj, const char *set_name,
 | |
| -                     GHashTable *node_hash, void *hash,
 | |
| -                     const char *always_first, gboolean overwrite,
 | |
| -                     crm_time_t *now, crm_time_t *next_change,
 | |
| +                     void *hash, const char *always_first, gboolean overwrite,
 | |
| +                     pe_rule_eval_data_t *rule_data, crm_time_t *next_change,
 | |
|                       GFunc unpack_func)
 | |
|  {
 | |
|      GList *pairs = make_pairs(top, xml_obj, set_name, always_first);
 | |
| @@ -678,11 +675,10 @@ unpack_nvpair_blocks(xmlNode *top, xmlNode *xml_obj, const char *set_name,
 | |
|      if (pairs) {
 | |
|          unpack_data_t data = {
 | |
|              .hash = hash,
 | |
| -            .node_hash = node_hash,
 | |
| -            .now = now,
 | |
|              .overwrite = overwrite,
 | |
|              .next_change = next_change,
 | |
|              .top = top,
 | |
| +            .rule_data = rule_data
 | |
|          };
 | |
|  
 | |
|          g_list_foreach(pairs, unpack_func, &data);
 | |
| @@ -709,8 +705,17 @@ pe_unpack_nvpairs(xmlNode *top, xmlNode *xml_obj, const char *set_name,
 | |
|                    const char *always_first, gboolean overwrite,
 | |
|                    crm_time_t *now, crm_time_t *next_change)
 | |
|  {
 | |
| -    unpack_nvpair_blocks(top, xml_obj, set_name, node_hash, hash, always_first,
 | |
| -                         overwrite, now, next_change, unpack_attr_set);
 | |
| +    pe_rule_eval_data_t rule_data = {
 | |
| +        .node_hash = node_hash,
 | |
| +        .role = RSC_ROLE_UNKNOWN,
 | |
| +        .now = now,
 | |
| +        .match_data = NULL,
 | |
| +        .rsc_data = NULL,
 | |
| +        .op_data = NULL
 | |
| +    };
 | |
| +
 | |
| +    unpack_nvpair_blocks(top, xml_obj, set_name, hash, always_first,
 | |
| +                         overwrite, &rule_data, next_change, unpack_attr_set);
 | |
|  }
 | |
|  
 | |
|  #if ENABLE_VERSIONED_ATTRS
 | |
| @@ -720,8 +725,17 @@ pe_unpack_versioned_attributes(xmlNode *top, xmlNode *xml_obj,
 | |
|                                 xmlNode *hash, crm_time_t *now,
 | |
|                                 crm_time_t *next_change)
 | |
|  {
 | |
| -    unpack_nvpair_blocks(top, xml_obj, set_name, node_hash, hash, NULL, FALSE,
 | |
| -                         now, next_change, unpack_versioned_attr_set);
 | |
| +    pe_rule_eval_data_t rule_data = {
 | |
| +        .node_hash = node_hash,
 | |
| +        .role = RSC_ROLE_UNKNOWN,
 | |
| +        .now = now,
 | |
| +        .match_data = NULL,
 | |
| +        .rsc_data = NULL,
 | |
| +        .op_data = NULL
 | |
| +    };
 | |
| +
 | |
| +    unpack_nvpair_blocks(top, xml_obj, set_name, hash, NULL, FALSE,
 | |
| +                         &rule_data, next_change, unpack_versioned_attr_set);
 | |
|  }
 | |
|  #endif
 | |
|  
 | |
| @@ -1366,6 +1380,15 @@ unpack_instance_attributes(xmlNode *top, xmlNode *xml_obj, const char *set_name,
 | |
|                             const char *always_first, gboolean overwrite,
 | |
|                             crm_time_t *now)
 | |
|  {
 | |
| -    unpack_nvpair_blocks(top, xml_obj, set_name, node_hash, hash, always_first,
 | |
| -                         overwrite, now, NULL, unpack_attr_set);
 | |
| +    pe_rule_eval_data_t rule_data = {
 | |
| +        .node_hash = node_hash,
 | |
| +        .role = RSC_ROLE_UNKNOWN,
 | |
| +        .now = now,
 | |
| +        .match_data = NULL,
 | |
| +        .rsc_data = NULL,
 | |
| +        .op_data = NULL
 | |
| +    };
 | |
| +
 | |
| +    unpack_nvpair_blocks(top, xml_obj, set_name, hash, always_first,
 | |
| +                         overwrite, &rule_data, NULL, unpack_attr_set);
 | |
|  }
 | |
| -- 
 | |
| 1.8.3.1
 | |
| 
 | |
| 
 | |
| From 54646db6f5e4f1bb141b35798bcad5c3cc025afe Mon Sep 17 00:00:00 2001
 | |
| From: Chris Lumens <clumens@redhat.com>
 | |
| Date: Wed, 8 Apr 2020 10:41:41 -0400
 | |
| Subject: [PATCH 06/17] Refactor: scheduler: Change args to
 | |
|  pe__unpack_dataset_nvpairs.
 | |
| 
 | |
| It should now take a pe_rule_eval_data_t instead of various separate
 | |
| arguments.  This will allow passing further data that needs to be tested
 | |
| against in the future (such as rsc_defaults and op_defaults).  It's also
 | |
| convenient to make versions of pe_unpack_nvpairs and
 | |
| pe_unpack_versioned_attributes that take the same arguments.
 | |
| 
 | |
| Then, adapt callers of pe__unpack_dataset_nvpairs to pass the new
 | |
| argument.
 | |
| ---
 | |
|  include/crm/pengine/internal.h |  2 +-
 | |
|  include/crm/pengine/rules.h    |  9 +++++++
 | |
|  lib/pengine/complex.c          | 41 ++++++++++++++++++++++-------
 | |
|  lib/pengine/rules.c            | 23 ++++++++++++++--
 | |
|  lib/pengine/unpack.c           | 33 ++++++++++++++++++++---
 | |
|  lib/pengine/utils.c            | 60 +++++++++++++++++++++++++++++++-----------
 | |
|  6 files changed, 137 insertions(+), 31 deletions(-)
 | |
| 
 | |
| diff --git a/include/crm/pengine/internal.h b/include/crm/pengine/internal.h
 | |
| index 189ba7b..3e59502 100644
 | |
| --- a/include/crm/pengine/internal.h
 | |
| +++ b/include/crm/pengine/internal.h
 | |
| @@ -460,7 +460,7 @@ void pe__update_recheck_time(time_t recheck, pe_working_set_t *data_set);
 | |
|  void pe__register_messages(pcmk__output_t *out);
 | |
|  
 | |
|  void pe__unpack_dataset_nvpairs(xmlNode *xml_obj, const char *set_name,
 | |
| -                                GHashTable *node_hash, GHashTable *hash,
 | |
| +                                pe_rule_eval_data_t *rule_data, GHashTable *hash,
 | |
|                                  const char *always_first, gboolean overwrite,
 | |
|                                  pe_working_set_t *data_set);
 | |
|  
 | |
| diff --git a/include/crm/pengine/rules.h b/include/crm/pengine/rules.h
 | |
| index a74c629..cbae8ed 100644
 | |
| --- a/include/crm/pengine/rules.h
 | |
| +++ b/include/crm/pengine/rules.h
 | |
| @@ -46,12 +46,21 @@ gboolean pe_test_expression(xmlNode *expr, GHashTable *node_hash,
 | |
|                              crm_time_t *next_change,
 | |
|                              pe_match_data_t *match_data);
 | |
|  
 | |
| +void pe_eval_nvpairs(xmlNode *top, xmlNode *xml_obj, const char *set_name,
 | |
| +                     pe_rule_eval_data_t *rule_data, GHashTable *hash,
 | |
| +                     const char *always_first, gboolean overwrite,
 | |
| +                     crm_time_t *next_change);
 | |
| +
 | |
|  void pe_unpack_nvpairs(xmlNode *top, xmlNode *xml_obj, const char *set_name,
 | |
|                         GHashTable *node_hash, GHashTable *hash,
 | |
|                         const char *always_first, gboolean overwrite,
 | |
|                         crm_time_t *now, crm_time_t *next_change);
 | |
|  
 | |
|  #if ENABLE_VERSIONED_ATTRS
 | |
| +void pe_eval_versioned_attributes(xmlNode *top, xmlNode *xml_obj,
 | |
| +                                  const char *set_name, pe_rule_eval_data_t *rule_data,
 | |
| +                                  xmlNode *hash, crm_time_t *next_change);
 | |
| +
 | |
|  void pe_unpack_versioned_attributes(xmlNode *top, xmlNode *xml_obj,
 | |
|                                      const char *set_name, GHashTable *node_hash,
 | |
|                                      xmlNode *hash, crm_time_t *now,
 | |
| diff --git a/lib/pengine/complex.c b/lib/pengine/complex.c
 | |
| index 16f3a71..d91c95e 100644
 | |
| --- a/lib/pengine/complex.c
 | |
| +++ b/lib/pengine/complex.c
 | |
| @@ -95,10 +95,17 @@ void
 | |
|  get_meta_attributes(GHashTable * meta_hash, pe_resource_t * rsc,
 | |
|                      pe_node_t * node, pe_working_set_t * data_set)
 | |
|  {
 | |
| -    GHashTable *node_hash = NULL;
 | |
| +    pe_rule_eval_data_t rule_data = {
 | |
| +        .node_hash = NULL,
 | |
| +        .role = RSC_ROLE_UNKNOWN,
 | |
| +        .now = data_set->now,
 | |
| +        .match_data = NULL,
 | |
| +        .rsc_data = NULL,
 | |
| +        .op_data = NULL
 | |
| +    };
 | |
|  
 | |
|      if (node) {
 | |
| -        node_hash = node->details->attrs;
 | |
| +        rule_data.node_hash = node->details->attrs;
 | |
|      }
 | |
|  
 | |
|      if (rsc->xml) {
 | |
| @@ -112,7 +119,7 @@ get_meta_attributes(GHashTable * meta_hash, pe_resource_t * rsc,
 | |
|          }
 | |
|      }
 | |
|  
 | |
| -    pe__unpack_dataset_nvpairs(rsc->xml, XML_TAG_META_SETS, node_hash,
 | |
| +    pe__unpack_dataset_nvpairs(rsc->xml, XML_TAG_META_SETS, &rule_data,
 | |
|                                 meta_hash, NULL, FALSE, data_set);
 | |
|  
 | |
|      /* set anything else based on the parent */
 | |
| @@ -122,20 +129,27 @@ get_meta_attributes(GHashTable * meta_hash, pe_resource_t * rsc,
 | |
|  
 | |
|      /* and finally check the defaults */
 | |
|      pe__unpack_dataset_nvpairs(data_set->rsc_defaults, XML_TAG_META_SETS,
 | |
| -                               node_hash, meta_hash, NULL, FALSE, data_set);
 | |
| +                               &rule_data, meta_hash, NULL, FALSE, data_set);
 | |
|  }
 | |
|  
 | |
|  void
 | |
|  get_rsc_attributes(GHashTable * meta_hash, pe_resource_t * rsc,
 | |
|                     pe_node_t * node, pe_working_set_t * data_set)
 | |
|  {
 | |
| -    GHashTable *node_hash = NULL;
 | |
| +    pe_rule_eval_data_t rule_data = {
 | |
| +        .node_hash = NULL,
 | |
| +        .role = RSC_ROLE_UNKNOWN,
 | |
| +        .now = data_set->now,
 | |
| +        .match_data = NULL,
 | |
| +        .rsc_data = NULL,
 | |
| +        .op_data = NULL
 | |
| +    };
 | |
|  
 | |
|      if (node) {
 | |
| -        node_hash = node->details->attrs;
 | |
| +        rule_data.node_hash = node->details->attrs;
 | |
|      }
 | |
|  
 | |
| -    pe__unpack_dataset_nvpairs(rsc->xml, XML_TAG_ATTR_SETS, node_hash,
 | |
| +    pe__unpack_dataset_nvpairs(rsc->xml, XML_TAG_ATTR_SETS, &rule_data,
 | |
|                                 meta_hash, NULL, FALSE, data_set);
 | |
|  
 | |
|      /* set anything else based on the parent */
 | |
| @@ -145,7 +159,7 @@ get_rsc_attributes(GHashTable * meta_hash, pe_resource_t * rsc,
 | |
|      } else {
 | |
|          /* and finally check the defaults */
 | |
|          pe__unpack_dataset_nvpairs(data_set->rsc_defaults, XML_TAG_ATTR_SETS,
 | |
| -                                   node_hash, meta_hash, NULL, FALSE, data_set);
 | |
| +                                   &rule_data, meta_hash, NULL, FALSE, data_set);
 | |
|      }
 | |
|  }
 | |
|  
 | |
| @@ -376,6 +390,15 @@ common_unpack(xmlNode * xml_obj, pe_resource_t ** rsc,
 | |
|      bool remote_node = FALSE;
 | |
|      bool has_versioned_params = FALSE;
 | |
|  
 | |
| +    pe_rule_eval_data_t rule_data = {
 | |
| +        .node_hash = NULL,
 | |
| +        .role = RSC_ROLE_UNKNOWN,
 | |
| +        .now = data_set->now,
 | |
| +        .match_data = NULL,
 | |
| +        .rsc_data = NULL,
 | |
| +        .op_data = NULL
 | |
| +    };
 | |
| +
 | |
|      crm_log_xml_trace(xml_obj, "Processing resource input...");
 | |
|  
 | |
|      if (id == NULL) {
 | |
| @@ -706,7 +729,7 @@ common_unpack(xmlNode * xml_obj, pe_resource_t ** rsc,
 | |
|  
 | |
|      (*rsc)->utilization = crm_str_table_new();
 | |
|  
 | |
| -    pe__unpack_dataset_nvpairs((*rsc)->xml, XML_TAG_UTILIZATION, NULL,
 | |
| +    pe__unpack_dataset_nvpairs((*rsc)->xml, XML_TAG_UTILIZATION, &rule_data,
 | |
|                                 (*rsc)->utilization, NULL, FALSE, data_set);
 | |
|  
 | |
|  /* 	data_set->resources = g_list_append(data_set->resources, (*rsc)); */
 | |
| diff --git a/lib/pengine/rules.c b/lib/pengine/rules.c
 | |
| index 2709d68..7575011 100644
 | |
| --- a/lib/pengine/rules.c
 | |
| +++ b/lib/pengine/rules.c
 | |
| @@ -686,6 +686,16 @@ unpack_nvpair_blocks(xmlNode *top, xmlNode *xml_obj, const char *set_name,
 | |
|      }
 | |
|  }
 | |
|  
 | |
| +void
 | |
| +pe_eval_nvpairs(xmlNode *top, xmlNode *xml_obj, const char *set_name,
 | |
| +                pe_rule_eval_data_t *rule_data, GHashTable *hash,
 | |
| +                const char *always_first, gboolean overwrite,
 | |
| +                crm_time_t *next_change)
 | |
| +{
 | |
| +    unpack_nvpair_blocks(top, xml_obj, set_name, hash, always_first,
 | |
| +                         overwrite, rule_data, next_change, unpack_attr_set);
 | |
| +}
 | |
| +
 | |
|  /*!
 | |
|   * \brief Extract nvpair blocks contained by an XML element into a hash table
 | |
|   *
 | |
| @@ -714,12 +724,21 @@ pe_unpack_nvpairs(xmlNode *top, xmlNode *xml_obj, const char *set_name,
 | |
|          .op_data = NULL
 | |
|      };
 | |
|  
 | |
| -    unpack_nvpair_blocks(top, xml_obj, set_name, hash, always_first,
 | |
| -                         overwrite, &rule_data, next_change, unpack_attr_set);
 | |
| +    pe_eval_nvpairs(top, xml_obj, set_name, &rule_data, hash,
 | |
| +                    always_first, overwrite, next_change);
 | |
|  }
 | |
|  
 | |
|  #if ENABLE_VERSIONED_ATTRS
 | |
|  void
 | |
| +pe_eval_versioned_attributes(xmlNode *top, xmlNode *xml_obj, const char *set_name,
 | |
| +                             pe_rule_eval_data_t *rule_data, xmlNode *hash,
 | |
| +                             crm_time_t *next_change)
 | |
| +{
 | |
| +    unpack_nvpair_blocks(top, xml_obj, set_name, hash, NULL, FALSE, rule_data,
 | |
| +                         next_change, unpack_versioned_attr_set);
 | |
| +}
 | |
| +
 | |
| +void
 | |
|  pe_unpack_versioned_attributes(xmlNode *top, xmlNode *xml_obj,
 | |
|                                 const char *set_name, GHashTable *node_hash,
 | |
|                                 xmlNode *hash, crm_time_t *now,
 | |
| diff --git a/lib/pengine/unpack.c b/lib/pengine/unpack.c
 | |
| index 532a3e6..8784857 100644
 | |
| --- a/lib/pengine/unpack.c
 | |
| +++ b/lib/pengine/unpack.c
 | |
| @@ -188,9 +188,18 @@ unpack_config(xmlNode * config, pe_working_set_t * data_set)
 | |
|      const char *value = NULL;
 | |
|      GHashTable *config_hash = crm_str_table_new();
 | |
|  
 | |
| +    pe_rule_eval_data_t rule_data = {
 | |
| +        .node_hash = NULL,
 | |
| +        .role = RSC_ROLE_UNKNOWN,
 | |
| +        .now = data_set->now,
 | |
| +        .match_data = NULL,
 | |
| +        .rsc_data = NULL,
 | |
| +        .op_data = NULL
 | |
| +    };
 | |
| +
 | |
|      data_set->config_hash = config_hash;
 | |
|  
 | |
| -    pe__unpack_dataset_nvpairs(config, XML_CIB_TAG_PROPSET, NULL, config_hash,
 | |
| +    pe__unpack_dataset_nvpairs(config, XML_CIB_TAG_PROPSET, &rule_data, config_hash,
 | |
|                                 CIB_OPTIONS_FIRST, FALSE, data_set);
 | |
|  
 | |
|      verify_pe_options(data_set->config_hash);
 | |
| @@ -515,6 +524,15 @@ unpack_nodes(xmlNode * xml_nodes, pe_working_set_t * data_set)
 | |
|      const char *type = NULL;
 | |
|      const char *score = NULL;
 | |
|  
 | |
| +    pe_rule_eval_data_t rule_data = {
 | |
| +        .node_hash = NULL,
 | |
| +        .role = RSC_ROLE_UNKNOWN,
 | |
| +        .now = data_set->now,
 | |
| +        .match_data = NULL,
 | |
| +        .rsc_data = NULL,
 | |
| +        .op_data = NULL
 | |
| +    };
 | |
| +
 | |
|      for (xml_obj = __xml_first_child_element(xml_nodes); xml_obj != NULL;
 | |
|           xml_obj = __xml_next_element(xml_obj)) {
 | |
|  
 | |
| @@ -547,7 +565,7 @@ unpack_nodes(xmlNode * xml_nodes, pe_working_set_t * data_set)
 | |
|              handle_startup_fencing(data_set, new_node);
 | |
|  
 | |
|              add_node_attrs(xml_obj, new_node, FALSE, data_set);
 | |
| -            pe__unpack_dataset_nvpairs(xml_obj, XML_TAG_UTILIZATION, NULL,
 | |
| +            pe__unpack_dataset_nvpairs(xml_obj, XML_TAG_UTILIZATION, &rule_data,
 | |
|                                         new_node->details->utilization, NULL,
 | |
|                                         FALSE, data_set);
 | |
|  
 | |
| @@ -3698,6 +3716,15 @@ add_node_attrs(xmlNode *xml_obj, pe_node_t *node, bool overwrite,
 | |
|  {
 | |
|      const char *cluster_name = NULL;
 | |
|  
 | |
| +    pe_rule_eval_data_t rule_data = {
 | |
| +        .node_hash = NULL,
 | |
| +        .role = RSC_ROLE_UNKNOWN,
 | |
| +        .now = data_set->now,
 | |
| +        .match_data = NULL,
 | |
| +        .rsc_data = NULL,
 | |
| +        .op_data = NULL
 | |
| +    };
 | |
| +
 | |
|      g_hash_table_insert(node->details->attrs,
 | |
|                          strdup(CRM_ATTR_UNAME), strdup(node->details->uname));
 | |
|  
 | |
| @@ -3719,7 +3746,7 @@ add_node_attrs(xmlNode *xml_obj, pe_node_t *node, bool overwrite,
 | |
|                              strdup(cluster_name));
 | |
|      }
 | |
|  
 | |
| -    pe__unpack_dataset_nvpairs(xml_obj, XML_TAG_ATTR_SETS, NULL,
 | |
| +    pe__unpack_dataset_nvpairs(xml_obj, XML_TAG_ATTR_SETS, &rule_data,
 | |
|                                 node->details->attrs, NULL, overwrite, data_set);
 | |
|  
 | |
|      if (pe_node_attribute_raw(node, CRM_ATTR_SITE_NAME) == NULL) {
 | |
| diff --git a/lib/pengine/utils.c b/lib/pengine/utils.c
 | |
| index c9b45e0..d01936d 100644
 | |
| --- a/lib/pengine/utils.c
 | |
| +++ b/lib/pengine/utils.c
 | |
| @@ -597,10 +597,19 @@ custom_action(pe_resource_t * rsc, char *key, const char *task,
 | |
|  
 | |
|          if (is_set(action->flags, pe_action_have_node_attrs) == FALSE
 | |
|              && action->node != NULL && action->op_entry != NULL) {
 | |
| +            pe_rule_eval_data_t rule_data = {
 | |
| +                .node_hash = action->node->details->attrs,
 | |
| +                .role = RSC_ROLE_UNKNOWN,
 | |
| +                .now = data_set->now,
 | |
| +                .match_data = NULL,
 | |
| +                .rsc_data = NULL,
 | |
| +                .op_data = NULL
 | |
| +            };
 | |
| +
 | |
|              pe_set_action_bit(action, pe_action_have_node_attrs);
 | |
|              pe__unpack_dataset_nvpairs(action->op_entry, XML_TAG_ATTR_SETS,
 | |
| -                                       action->node->details->attrs,
 | |
| -                                       action->extra, NULL, FALSE, data_set);
 | |
| +                                       &rule_data, action->extra, NULL,
 | |
| +                                       FALSE, data_set);
 | |
|          }
 | |
|  
 | |
|          if (is_set(action->flags, pe_action_pseudo)) {
 | |
| @@ -873,6 +882,15 @@ pe_get_configured_timeout(pe_resource_t *rsc, const char *action, pe_working_set
 | |
|      const char *timeout = NULL;
 | |
|      int timeout_ms = 0;
 | |
|  
 | |
| +    pe_rule_eval_data_t rule_data = {
 | |
| +        .node_hash = NULL,
 | |
| +        .role = RSC_ROLE_UNKNOWN,
 | |
| +        .now = data_set->now,
 | |
| +        .match_data = NULL,
 | |
| +        .rsc_data = NULL,
 | |
| +        .op_data = NULL
 | |
| +    };
 | |
| +
 | |
|      for (child = first_named_child(rsc->ops_xml, XML_ATTR_OP);
 | |
|           child != NULL; child = crm_next_same_xml(child)) {
 | |
|          if (safe_str_eq(action, crm_element_value(child, XML_NVPAIR_ATTR_NAME))) {
 | |
| @@ -884,7 +902,7 @@ pe_get_configured_timeout(pe_resource_t *rsc, const char *action, pe_working_set
 | |
|      if (timeout == NULL && data_set->op_defaults) {
 | |
|          GHashTable *action_meta = crm_str_table_new();
 | |
|          pe__unpack_dataset_nvpairs(data_set->op_defaults, XML_TAG_META_SETS,
 | |
| -                                   NULL, action_meta, NULL, FALSE, data_set);
 | |
| +                                   &rule_data, action_meta, NULL, FALSE, data_set);
 | |
|          timeout = g_hash_table_lookup(action_meta, XML_ATTR_TIMEOUT);
 | |
|      }
 | |
|  
 | |
| @@ -964,10 +982,19 @@ unpack_operation(pe_action_t * action, xmlNode * xml_obj, pe_resource_t * contai
 | |
|      pe_rsc_action_details_t *rsc_details = NULL;
 | |
|  #endif
 | |
|  
 | |
| +    pe_rule_eval_data_t rule_data = {
 | |
| +        .node_hash = NULL,
 | |
| +        .role = RSC_ROLE_UNKNOWN,
 | |
| +        .now = data_set->now,
 | |
| +        .match_data = NULL,
 | |
| +        .rsc_data = NULL,
 | |
| +        .op_data = NULL
 | |
| +    };
 | |
| +
 | |
|      CRM_CHECK(action && action->rsc, return);
 | |
|  
 | |
|      // Cluster-wide <op_defaults> <meta_attributes>
 | |
| -    pe__unpack_dataset_nvpairs(data_set->op_defaults, XML_TAG_META_SETS, NULL,
 | |
| +    pe__unpack_dataset_nvpairs(data_set->op_defaults, XML_TAG_META_SETS, &rule_data,
 | |
|                                 action->meta, NULL, FALSE, data_set);
 | |
|  
 | |
|      // Probe timeouts default differently, so handle timeout default later
 | |
| @@ -981,19 +1008,20 @@ unpack_operation(pe_action_t * action, xmlNode * xml_obj, pe_resource_t * contai
 | |
|          xmlAttrPtr xIter = NULL;
 | |
|  
 | |
|          // <op> <meta_attributes> take precedence over defaults
 | |
| -        pe__unpack_dataset_nvpairs(xml_obj, XML_TAG_META_SETS, NULL,
 | |
| +        pe__unpack_dataset_nvpairs(xml_obj, XML_TAG_META_SETS, &rule_data,
 | |
|                                     action->meta, NULL, TRUE, data_set);
 | |
|  
 | |
|  #if ENABLE_VERSIONED_ATTRS
 | |
|          rsc_details = pe_rsc_action_details(action);
 | |
| -        pe_unpack_versioned_attributes(data_set->input, xml_obj,
 | |
| -                                       XML_TAG_ATTR_SETS, NULL,
 | |
| -                                       rsc_details->versioned_parameters,
 | |
| -                                       data_set->now, NULL);
 | |
| -        pe_unpack_versioned_attributes(data_set->input, xml_obj,
 | |
| -                                       XML_TAG_META_SETS, NULL,
 | |
| -                                       rsc_details->versioned_meta,
 | |
| -                                       data_set->now, NULL);
 | |
| +
 | |
| +        pe_eval_versioned_attributes(data_set->input, xml_obj,
 | |
| +                                     XML_TAG_ATTR_SETS, &rule_data,
 | |
| +                                     rsc_details->versioned_parameters,
 | |
| +                                     NULL);
 | |
| +        pe_eval_versioned_attributes(data_set->input, xml_obj,
 | |
| +                                     XML_TAG_META_SETS, &rule_data,
 | |
| +                                     rsc_details->versioned_meta,
 | |
| +                                     NULL);
 | |
|  #endif
 | |
|  
 | |
|          /* Anything set as an <op> XML property has highest precedence.
 | |
| @@ -2693,14 +2721,14 @@ pe__update_recheck_time(time_t recheck, pe_working_set_t *data_set)
 | |
|   */
 | |
|  void
 | |
|  pe__unpack_dataset_nvpairs(xmlNode *xml_obj, const char *set_name,
 | |
| -                           GHashTable *node_hash, GHashTable *hash,
 | |
| +                           pe_rule_eval_data_t *rule_data, GHashTable *hash,
 | |
|                             const char *always_first, gboolean overwrite,
 | |
|                             pe_working_set_t *data_set)
 | |
|  {
 | |
|      crm_time_t *next_change = crm_time_new_undefined();
 | |
|  
 | |
| -    pe_unpack_nvpairs(data_set->input, xml_obj, set_name, node_hash, hash,
 | |
| -                      always_first, overwrite, data_set->now, next_change);
 | |
| +    pe_eval_nvpairs(data_set->input, xml_obj, set_name, rule_data, hash,
 | |
| +                    always_first, overwrite, next_change);
 | |
|      if (crm_time_is_defined(next_change)) {
 | |
|          time_t recheck = (time_t) crm_time_get_seconds_since_epoch(next_change);
 | |
|  
 | |
| -- 
 | |
| 1.8.3.1
 | |
| 
 | |
| 
 | |
| From ad06f60bae1fcb5d204fa18a0b21ade78aaee5f4 Mon Sep 17 00:00:00 2001
 | |
| From: Chris Lumens <clumens@redhat.com>
 | |
| Date: Wed, 8 Apr 2020 13:43:26 -0400
 | |
| Subject: [PATCH 07/17] Refactor: scheduler: unpack_operation should be static.
 | |
| 
 | |
| ---
 | |
|  lib/pengine/utils.c | 6 +++---
 | |
|  1 file changed, 3 insertions(+), 3 deletions(-)
 | |
| 
 | |
| diff --git a/lib/pengine/utils.c b/lib/pengine/utils.c
 | |
| index d01936d..c345875 100644
 | |
| --- a/lib/pengine/utils.c
 | |
| +++ b/lib/pengine/utils.c
 | |
| @@ -23,8 +23,8 @@
 | |
|  extern xmlNode *get_object_root(const char *object_type, xmlNode * the_root);
 | |
|  void print_str_str(gpointer key, gpointer value, gpointer user_data);
 | |
|  gboolean ghash_free_str_str(gpointer key, gpointer value, gpointer user_data);
 | |
| -void unpack_operation(pe_action_t * action, xmlNode * xml_obj, pe_resource_t * container,
 | |
| -                      pe_working_set_t * data_set);
 | |
| +static void unpack_operation(pe_action_t * action, xmlNode * xml_obj, pe_resource_t * container,
 | |
| +                             pe_working_set_t * data_set);
 | |
|  static xmlNode *find_rsc_op_entry_helper(pe_resource_t * rsc, const char *key,
 | |
|                                           gboolean include_disabled);
 | |
|  
 | |
| @@ -968,7 +968,7 @@ unpack_versioned_meta(xmlNode *versioned_meta, xmlNode *xml_obj,
 | |
|   * \param[in]     container  Resource that contains affected resource, if any
 | |
|   * \param[in]     data_set   Cluster state
 | |
|   */
 | |
| -void
 | |
| +static void
 | |
|  unpack_operation(pe_action_t * action, xmlNode * xml_obj, pe_resource_t * container,
 | |
|                   pe_working_set_t * data_set)
 | |
|  {
 | |
| -- 
 | |
| 1.8.3.1
 | |
| 
 | |
| 
 | |
| From 7e57d955c9209af62dffc0639c50d51121028c26 Mon Sep 17 00:00:00 2001
 | |
| From: Chris Lumens <clumens@redhat.com>
 | |
| Date: Wed, 8 Apr 2020 14:58:35 -0400
 | |
| Subject: [PATCH 08/17] Refactor: scheduler: Pass interval to unpack_operation.
 | |
| 
 | |
| ---
 | |
|  lib/pengine/utils.c | 36 ++++++++++++++----------------------
 | |
|  1 file changed, 14 insertions(+), 22 deletions(-)
 | |
| 
 | |
| diff --git a/lib/pengine/utils.c b/lib/pengine/utils.c
 | |
| index c345875..1e3b0bd 100644
 | |
| --- a/lib/pengine/utils.c
 | |
| +++ b/lib/pengine/utils.c
 | |
| @@ -24,7 +24,7 @@ extern xmlNode *get_object_root(const char *object_type, xmlNode * the_root);
 | |
|  void print_str_str(gpointer key, gpointer value, gpointer user_data);
 | |
|  gboolean ghash_free_str_str(gpointer key, gpointer value, gpointer user_data);
 | |
|  static void unpack_operation(pe_action_t * action, xmlNode * xml_obj, pe_resource_t * container,
 | |
| -                             pe_working_set_t * data_set);
 | |
| +                             pe_working_set_t * data_set, guint interval_ms);
 | |
|  static xmlNode *find_rsc_op_entry_helper(pe_resource_t * rsc, const char *key,
 | |
|                                           gboolean include_disabled);
 | |
|  
 | |
| @@ -568,9 +568,13 @@ custom_action(pe_resource_t * rsc, char *key, const char *task,
 | |
|          }
 | |
|  
 | |
|          if (rsc != NULL) {
 | |
| +            guint interval_ms = 0;
 | |
| +
 | |
|              action->op_entry = find_rsc_op_entry_helper(rsc, key, TRUE);
 | |
| +            parse_op_key(key, NULL, NULL, &interval_ms);
 | |
|  
 | |
| -            unpack_operation(action, action->op_entry, rsc->container, data_set);
 | |
| +            unpack_operation(action, action->op_entry, rsc->container, data_set,
 | |
| +                             interval_ms);
 | |
|  
 | |
|              if (save_action) {
 | |
|                  rsc->actions = g_list_prepend(rsc->actions, action);
 | |
| @@ -963,20 +967,20 @@ unpack_versioned_meta(xmlNode *versioned_meta, xmlNode *xml_obj,
 | |
|   * and start delay values as integer milliseconds), requirements, and
 | |
|   * failure policy.
 | |
|   *
 | |
| - * \param[in,out] action     Action to unpack into
 | |
| - * \param[in]     xml_obj    Operation XML (or NULL if all defaults)
 | |
| - * \param[in]     container  Resource that contains affected resource, if any
 | |
| - * \param[in]     data_set   Cluster state
 | |
| + * \param[in,out] action      Action to unpack into
 | |
| + * \param[in]     xml_obj     Operation XML (or NULL if all defaults)
 | |
| + * \param[in]     container   Resource that contains affected resource, if any
 | |
| + * \param[in]     data_set    Cluster state
 | |
| + * \param[in]     interval_ms How frequently to perform the operation
 | |
|   */
 | |
|  static void
 | |
|  unpack_operation(pe_action_t * action, xmlNode * xml_obj, pe_resource_t * container,
 | |
| -                 pe_working_set_t * data_set)
 | |
| +                 pe_working_set_t * data_set, guint interval_ms)
 | |
|  {
 | |
| -    guint interval_ms = 0;
 | |
|      int timeout = 0;
 | |
|      char *value_ms = NULL;
 | |
|      const char *value = NULL;
 | |
| -    const char *field = NULL;
 | |
| +    const char *field = XML_LRM_ATTR_INTERVAL;
 | |
|      char *default_timeout = NULL;
 | |
|  #if ENABLE_VERSIONED_ATTRS
 | |
|      pe_rsc_action_details_t *rsc_details = NULL;
 | |
| @@ -1038,23 +1042,11 @@ unpack_operation(pe_action_t * action, xmlNode * xml_obj, pe_resource_t * contai
 | |
|      g_hash_table_remove(action->meta, "id");
 | |
|  
 | |
|      // Normalize interval to milliseconds
 | |
| -    field = XML_LRM_ATTR_INTERVAL;
 | |
| -    value = g_hash_table_lookup(action->meta, field);
 | |
| -    if (value != NULL) {
 | |
| -        interval_ms = crm_parse_interval_spec(value);
 | |
| -
 | |
| -    } else if ((xml_obj == NULL) && !strcmp(action->task, RSC_STATUS)) {
 | |
| -        /* An orphaned recurring monitor will not have any XML. However, we
 | |
| -         * want the interval to be set, so the action can be properly detected
 | |
| -         * as a recurring monitor. Parse it from the key in this case.
 | |
| -         */
 | |
| -        parse_op_key(action->uuid, NULL, NULL, &interval_ms);
 | |
| -    }
 | |
|      if (interval_ms > 0) {
 | |
|          value_ms = crm_strdup_printf("%u", interval_ms);
 | |
|          g_hash_table_replace(action->meta, strdup(field), value_ms);
 | |
|  
 | |
| -    } else if (value) {
 | |
| +    } else if (g_hash_table_lookup(action->meta, field) != NULL) {
 | |
|          g_hash_table_remove(action->meta, field);
 | |
|      }
 | |
|  
 | |
| -- 
 | |
| 1.8.3.1
 | |
| 
 | |
| 
 | |
| From e4c411d9674e222647dd3ed31714c369f54ccad1 Mon Sep 17 00:00:00 2001
 | |
| From: Chris Lumens <clumens@redhat.com>
 | |
| Date: Thu, 9 Apr 2020 16:15:17 -0400
 | |
| Subject: [PATCH 09/17] Feature: scheduler: Pass rsc_defaults and op_defaults
 | |
|  data.
 | |
| 
 | |
| See: rhbz#1628701.
 | |
| ---
 | |
|  lib/pengine/complex.c |  8 +++++++-
 | |
|  lib/pengine/utils.c   | 15 +++++++++++++--
 | |
|  2 files changed, 20 insertions(+), 3 deletions(-)
 | |
| 
 | |
| diff --git a/lib/pengine/complex.c b/lib/pengine/complex.c
 | |
| index d91c95e..1f06348 100644
 | |
| --- a/lib/pengine/complex.c
 | |
| +++ b/lib/pengine/complex.c
 | |
| @@ -95,12 +95,18 @@ void
 | |
|  get_meta_attributes(GHashTable * meta_hash, pe_resource_t * rsc,
 | |
|                      pe_node_t * node, pe_working_set_t * data_set)
 | |
|  {
 | |
| +    pe_rsc_eval_data_t rsc_rule_data = {
 | |
| +        .standard = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS),
 | |
| +        .provider = crm_element_value(rsc->xml, XML_AGENT_ATTR_PROVIDER),
 | |
| +        .agent = crm_element_value(rsc->xml, XML_EXPR_ATTR_TYPE)
 | |
| +    };
 | |
| +
 | |
|      pe_rule_eval_data_t rule_data = {
 | |
|          .node_hash = NULL,
 | |
|          .role = RSC_ROLE_UNKNOWN,
 | |
|          .now = data_set->now,
 | |
|          .match_data = NULL,
 | |
| -        .rsc_data = NULL,
 | |
| +        .rsc_data = &rsc_rule_data,
 | |
|          .op_data = NULL
 | |
|      };
 | |
|  
 | |
| diff --git a/lib/pengine/utils.c b/lib/pengine/utils.c
 | |
| index 1e3b0bd..d5309ed 100644
 | |
| --- a/lib/pengine/utils.c
 | |
| +++ b/lib/pengine/utils.c
 | |
| @@ -986,13 +986,24 @@ unpack_operation(pe_action_t * action, xmlNode * xml_obj, pe_resource_t * contai
 | |
|      pe_rsc_action_details_t *rsc_details = NULL;
 | |
|  #endif
 | |
|  
 | |
| +    pe_rsc_eval_data_t rsc_rule_data = {
 | |
| +        .standard = crm_element_value(action->rsc->xml, XML_AGENT_ATTR_CLASS),
 | |
| +        .provider = crm_element_value(action->rsc->xml, XML_AGENT_ATTR_PROVIDER),
 | |
| +        .agent = crm_element_value(action->rsc->xml, XML_EXPR_ATTR_TYPE)
 | |
| +    };
 | |
| +
 | |
| +    pe_op_eval_data_t op_rule_data = {
 | |
| +        .op_name = action->task,
 | |
| +        .interval = interval_ms
 | |
| +    };
 | |
| +
 | |
|      pe_rule_eval_data_t rule_data = {
 | |
|          .node_hash = NULL,
 | |
|          .role = RSC_ROLE_UNKNOWN,
 | |
|          .now = data_set->now,
 | |
|          .match_data = NULL,
 | |
| -        .rsc_data = NULL,
 | |
| -        .op_data = NULL
 | |
| +        .rsc_data = &rsc_rule_data,
 | |
| +        .op_data = &op_rule_data
 | |
|      };
 | |
|  
 | |
|      CRM_CHECK(action && action->rsc, return);
 | |
| -- 
 | |
| 1.8.3.1
 | |
| 
 | |
| 
 | |
| From 57eedcad739071530f01e1fd691734f7681a08a1 Mon Sep 17 00:00:00 2001
 | |
| From: Chris Lumens <clumens@redhat.com>
 | |
| Date: Fri, 17 Apr 2020 12:30:51 -0400
 | |
| Subject: [PATCH 10/17] Feature: xml: Add rsc_expression and op_expression to
 | |
|  the XML schema.
 | |
| 
 | |
| ---
 | |
|  cts/cli/regression.upgrade.exp  |   7 +-
 | |
|  cts/cli/regression.validity.exp |  22 ++-
 | |
|  xml/constraints-next.rng        |   4 +-
 | |
|  xml/nodes-3.4.rng               |  44 +++++
 | |
|  xml/nvset-3.4.rng               |  63 ++++++
 | |
|  xml/options-3.4.rng             | 111 +++++++++++
 | |
|  xml/resources-3.4.rng           | 425 ++++++++++++++++++++++++++++++++++++++++
 | |
|  xml/rule-3.4.rng                | 165 ++++++++++++++++
 | |
|  8 files changed, 833 insertions(+), 8 deletions(-)
 | |
|  create mode 100644 xml/nodes-3.4.rng
 | |
|  create mode 100644 xml/nvset-3.4.rng
 | |
|  create mode 100644 xml/options-3.4.rng
 | |
|  create mode 100644 xml/resources-3.4.rng
 | |
|  create mode 100644 xml/rule-3.4.rng
 | |
| 
 | |
| diff --git a/cts/cli/regression.upgrade.exp b/cts/cli/regression.upgrade.exp
 | |
| index 28ca057..50b22df 100644
 | |
| --- a/cts/cli/regression.upgrade.exp
 | |
| +++ b/cts/cli/regression.upgrade.exp
 | |
| @@ -79,8 +79,11 @@ update_validation 	debug: Configuration valid for schema: pacemaker-3.2
 | |
|  update_validation 	debug: pacemaker-3.2-style configuration is also valid for pacemaker-3.3
 | |
|  update_validation 	debug: Testing 'pacemaker-3.3' validation (17 of X)
 | |
|  update_validation 	debug: Configuration valid for schema: pacemaker-3.3
 | |
| -update_validation 	trace: Stopping at pacemaker-3.3
 | |
| -update_validation 	info: Transformed the configuration from pacemaker-2.10 to pacemaker-3.3
 | |
| +update_validation 	debug: pacemaker-3.3-style configuration is also valid for pacemaker-3.4
 | |
| +update_validation 	debug: Testing 'pacemaker-3.4' validation (18 of X)
 | |
| +update_validation 	debug: Configuration valid for schema: pacemaker-3.4
 | |
| +update_validation 	trace: Stopping at pacemaker-3.4
 | |
| +update_validation 	info: Transformed the configuration from pacemaker-2.10 to pacemaker-3.4
 | |
|  =#=#=#= Current cib after: Upgrade to latest CIB schema (trigger 2.10.xsl + the wrapping) =#=#=#=
 | |
|  <cib epoch="2" num_updates="0" admin_epoch="1">
 | |
|    <configuration>
 | |
| diff --git a/cts/cli/regression.validity.exp b/cts/cli/regression.validity.exp
 | |
| index 46e54b5..4407074 100644
 | |
| --- a/cts/cli/regression.validity.exp
 | |
| +++ b/cts/cli/regression.validity.exp
 | |
| @@ -105,7 +105,11 @@ update_validation 	debug: Testing 'pacemaker-3.3' validation (17 of X)
 | |
|  element rsc_order: Relax-NG validity error : Invalid attribute first-action for element rsc_order
 | |
|  element rsc_order: Relax-NG validity error : Element constraints has extra content: rsc_order
 | |
|  update_validation 	trace: pacemaker-3.3 validation failed
 | |
| -Cannot upgrade configuration (claiming schema pacemaker-1.2) to at least pacemaker-3.0 because it does not validate with any schema from pacemaker-1.2 to pacemaker-3.3
 | |
| +update_validation 	debug: Testing 'pacemaker-3.4' validation (18 of X)
 | |
| +element rsc_order: Relax-NG validity error : Invalid attribute first-action for element rsc_order
 | |
| +element rsc_order: Relax-NG validity error : Element constraints has extra content: rsc_order
 | |
| +update_validation 	trace: pacemaker-3.4 validation failed
 | |
| +Cannot upgrade configuration (claiming schema pacemaker-1.2) to at least pacemaker-3.0 because it does not validate with any schema from pacemaker-1.2 to pacemaker-3.4
 | |
|  =#=#=#= End test: Run crm_simulate with invalid CIB (enum violation) - Invalid configuration (78) =#=#=#=
 | |
|  * Passed: crm_simulate   - Run crm_simulate with invalid CIB (enum violation)
 | |
|  =#=#=#= Begin test: Try to make resulting CIB invalid (unrecognized validate-with) =#=#=#=
 | |
| @@ -198,7 +202,10 @@ update_validation 	trace: pacemaker-3.2 validation failed
 | |
|  update_validation 	debug: Testing 'pacemaker-3.3' validation (17 of X)
 | |
|  element cib: Relax-NG validity error : Invalid attribute validate-with for element cib
 | |
|  update_validation 	trace: pacemaker-3.3 validation failed
 | |
| -Cannot upgrade configuration (claiming schema pacemaker-9999.0) to at least pacemaker-3.0 because it does not validate with any schema from unknown to pacemaker-3.3
 | |
| +update_validation 	debug: Testing 'pacemaker-3.4' validation (18 of X)
 | |
| +element cib: Relax-NG validity error : Invalid attribute validate-with for element cib
 | |
| +update_validation 	trace: pacemaker-3.4 validation failed
 | |
| +Cannot upgrade configuration (claiming schema pacemaker-9999.0) to at least pacemaker-3.0 because it does not validate with any schema from unknown to pacemaker-3.4
 | |
|  =#=#=#= End test: Run crm_simulate with invalid CIB (unrecognized validate-with) - Invalid configuration (78) =#=#=#=
 | |
|  * Passed: crm_simulate   - Run crm_simulate with invalid CIB (unrecognized validate-with)
 | |
|  =#=#=#= Begin test: Try to make resulting CIB invalid, but possibly recoverable (valid with X.Y+1) =#=#=#=
 | |
| @@ -286,8 +293,11 @@ update_validation 	debug: Configuration valid for schema: pacemaker-3.2
 | |
|  update_validation 	debug: pacemaker-3.2-style configuration is also valid for pacemaker-3.3
 | |
|  update_validation 	debug: Testing 'pacemaker-3.3' validation (17 of X)
 | |
|  update_validation 	debug: Configuration valid for schema: pacemaker-3.3
 | |
| -update_validation 	trace: Stopping at pacemaker-3.3
 | |
| -update_validation 	info: Transformed the configuration from pacemaker-1.2 to pacemaker-3.3
 | |
| +update_validation 	debug: pacemaker-3.3-style configuration is also valid for pacemaker-3.4
 | |
| +update_validation 	debug: Testing 'pacemaker-3.4' validation (18 of X)
 | |
| +update_validation 	debug: Configuration valid for schema: pacemaker-3.4
 | |
| +update_validation 	trace: Stopping at pacemaker-3.4
 | |
| +update_validation 	info: Transformed the configuration from pacemaker-1.2 to pacemaker-3.4
 | |
|  unpack_resources 	error: Resource start-up disabled since no STONITH resources have been defined
 | |
|  unpack_resources 	error: Either configure some or disable STONITH with the stonith-enabled option
 | |
|  unpack_resources 	error: NOTE: Clusters with shared data need STONITH to ensure data integrity
 | |
| @@ -393,6 +403,8 @@ element rsc_order: Relax-NG validity error : Invalid attribute first-action for
 | |
|  element rsc_order: Relax-NG validity error : Element constraints has extra content: rsc_order
 | |
|  element rsc_order: Relax-NG validity error : Invalid attribute first-action for element rsc_order
 | |
|  element rsc_order: Relax-NG validity error : Element constraints has extra content: rsc_order
 | |
| +element rsc_order: Relax-NG validity error : Invalid attribute first-action for element rsc_order
 | |
| +element rsc_order: Relax-NG validity error : Element constraints has extra content: rsc_order
 | |
|  =#=#=#= Current cib after: Make resulting CIB invalid, and without validate-with attribute =#=#=#=
 | |
|  <cib epoch="31" num_updates="0" admin_epoch="0" validate-with="none">
 | |
|    <configuration>
 | |
| @@ -450,6 +462,8 @@ validity.bad.xml:10: element rsc_order: Relax-NG validity error : Invalid attrib
 | |
|  validity.bad.xml:10: element rsc_order: Relax-NG validity error : Element constraints has extra content: rsc_order
 | |
|  validity.bad.xml:10: element rsc_order: Relax-NG validity error : Invalid attribute first-action for element rsc_order
 | |
|  validity.bad.xml:10: element rsc_order: Relax-NG validity error : Element constraints has extra content: rsc_order
 | |
| +validity.bad.xml:10: element rsc_order: Relax-NG validity error : Invalid attribute first-action for element rsc_order
 | |
| +validity.bad.xml:10: element rsc_order: Relax-NG validity error : Element constraints has extra content: rsc_order
 | |
|  unpack_resources 	error: Resource start-up disabled since no STONITH resources have been defined
 | |
|  unpack_resources 	error: Either configure some or disable STONITH with the stonith-enabled option
 | |
|  unpack_resources 	error: NOTE: Clusters with shared data need STONITH to ensure data integrity
 | |
| diff --git a/xml/constraints-next.rng b/xml/constraints-next.rng
 | |
| index 7e0d98e..1fa3e75 100644
 | |
| --- a/xml/constraints-next.rng
 | |
| +++ b/xml/constraints-next.rng
 | |
| @@ -43,7 +43,7 @@
 | |
|            <attribute name="node"><text/></attribute>
 | |
|          </group>
 | |
|          <oneOrMore>
 | |
| -          <externalRef href="rule-2.9.rng"/>
 | |
| +          <externalRef href="rule-3.4.rng"/>
 | |
|          </oneOrMore>
 | |
|        </choice>
 | |
|        <optional>
 | |
| @@ -255,7 +255,7 @@
 | |
|    <define name="element-lifetime">
 | |
|      <element name="lifetime">
 | |
|        <oneOrMore>
 | |
| -        <externalRef href="rule-2.9.rng"/>
 | |
| +        <externalRef href="rule-3.4.rng"/>
 | |
|        </oneOrMore>
 | |
|      </element>
 | |
|    </define>
 | |
| diff --git a/xml/nodes-3.4.rng b/xml/nodes-3.4.rng
 | |
| new file mode 100644
 | |
| index 0000000..0132c72
 | |
| --- /dev/null
 | |
| +++ b/xml/nodes-3.4.rng
 | |
| @@ -0,0 +1,44 @@
 | |
| +<?xml version="1.0" encoding="UTF-8"?>
 | |
| +<grammar xmlns="http://relaxng.org/ns/structure/1.0"
 | |
| +         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
 | |
| +  <start>
 | |
| +      <ref name="element-nodes"/>
 | |
| +  </start>
 | |
| +
 | |
| +  <define name="element-nodes">
 | |
| +    <element name="nodes">
 | |
| +      <zeroOrMore>
 | |
| +        <element name="node">
 | |
| +          <attribute name="id"><text/></attribute>
 | |
| +          <attribute name="uname"><text/></attribute>
 | |
| +          <optional>
 | |
| +            <attribute name="type">
 | |
| +              <choice>
 | |
| +                <value>member</value>
 | |
| +                <value>ping</value>
 | |
| +                <value>remote</value>
 | |
| +              </choice>
 | |
| +            </attribute>
 | |
| +          </optional>
 | |
| +          <optional>
 | |
| +            <attribute name="description"><text/></attribute>
 | |
| +          </optional>
 | |
| +          <optional>
 | |
| +            <externalRef href="score.rng"/>
 | |
| +          </optional>
 | |
| +          <zeroOrMore>
 | |
| +            <choice>
 | |
| +              <element name="instance_attributes">
 | |
| +                <externalRef href="nvset-3.4.rng"/>
 | |
| +              </element>
 | |
| +              <element name="utilization">
 | |
| +                <externalRef href="nvset-3.4.rng"/>
 | |
| +              </element>
 | |
| +            </choice>
 | |
| +          </zeroOrMore>
 | |
| +        </element>
 | |
| +      </zeroOrMore>
 | |
| +    </element>
 | |
| +  </define>
 | |
| +
 | |
| +</grammar>
 | |
| diff --git a/xml/nvset-3.4.rng b/xml/nvset-3.4.rng
 | |
| new file mode 100644
 | |
| index 0000000..91a7d23
 | |
| --- /dev/null
 | |
| +++ b/xml/nvset-3.4.rng
 | |
| @@ -0,0 +1,63 @@
 | |
| +<?xml version="1.0" encoding="UTF-8"?>
 | |
| +<!-- just as nvset-2.9.rng, but allows for instantiated @name restrictions -->
 | |
| +<grammar xmlns="http://relaxng.org/ns/structure/1.0" 
 | |
| +         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
 | |
| +  <start>
 | |
| +    <ref name="element-nvset"/>
 | |
| +  </start>
 | |
| +
 | |
| +  <!-- nvpair/@name:
 | |
| +       * generic string by default, parent grammar may want to prohibit
 | |
| +         enumerated names -->
 | |
| +  <define name="element-nvset.name">
 | |
| +    <attribute name="name">
 | |
| +      <text/>
 | |
| +    </attribute>
 | |
| +  </define>
 | |
| +
 | |
| +  <!-- nvpair/@name:
 | |
| +       * defer element-nvset.name grammar item
 | |
| +       nvpair/@value:
 | |
| +       generic string by default, parent grammar may want to restrict
 | |
| +       enumerated pairs (i.e. related to @name) at once -->
 | |
| +  <define name="element-nvset.name-value">
 | |
| +    <ref name="element-nvset.name"/>
 | |
| +    <optional>
 | |
| +      <attribute name="value"><text/></attribute>
 | |
| +    </optional>
 | |
| +  </define>
 | |
| +
 | |
| +  <define name="element-nvset">
 | |
| +   <choice>
 | |
| +   <attribute name="id-ref"><data type="IDREF"/></attribute>
 | |
| +   <group>
 | |
| +    <attribute name="id"><data type="ID"/></attribute>
 | |
| +    <interleave>
 | |
| +      <optional>
 | |
| +        <externalRef href="rule-3.4.rng"/>
 | |
| +      </optional>
 | |
| +        <zeroOrMore>
 | |
| +          <element name="nvpair">
 | |
| +            <choice>
 | |
| +              <group>
 | |
| +                <attribute name="id-ref"><data type="IDREF"/></attribute>
 | |
| +                <optional>
 | |
| +                  <attribute name="name"><text/></attribute>
 | |
| +                </optional>
 | |
| +              </group>
 | |
| +              <group>
 | |
| +                <attribute name="id"><data type="ID"/></attribute>
 | |
| +                <ref name="element-nvset.name-value"/>
 | |
| +              </group>
 | |
| +            </choice>
 | |
| +          </element>
 | |
| +        </zeroOrMore>
 | |
| +      <optional>
 | |
| +        <externalRef href="score.rng"/>
 | |
| +      </optional>
 | |
| +    </interleave>
 | |
| +   </group>
 | |
| +   </choice>
 | |
| +  </define>
 | |
| +
 | |
| +</grammar>
 | |
| diff --git a/xml/options-3.4.rng b/xml/options-3.4.rng
 | |
| new file mode 100644
 | |
| index 0000000..22330d8
 | |
| --- /dev/null
 | |
| +++ b/xml/options-3.4.rng
 | |
| @@ -0,0 +1,111 @@
 | |
| +<?xml version="1.0" encoding="UTF-8"?>
 | |
| +<grammar xmlns="http://relaxng.org/ns/structure/1.0"
 | |
| +         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
 | |
| +  <start>
 | |
| +    <ref name="options"/>
 | |
| +  </start>
 | |
| +
 | |
| +  <!--
 | |
| +   see upgrade-2.10.xsl
 | |
| +   - cibtr:table for="cluster-properties"
 | |
| +   -->
 | |
| +  <define name="cluster_property_set.nvpair.name-value-unsupported">
 | |
| +    <choice>
 | |
| +      <group>
 | |
| +        <attribute name="name">
 | |
| +          <value type="string">cluster-infrastructure</value>
 | |
| +        </attribute>
 | |
| +        <attribute name="value">
 | |
| +          <data type="string">
 | |
| +            <except>
 | |
| +              <choice>
 | |
| +                <value>heartbeat</value>
 | |
| +                <value>openais</value>
 | |
| +                <value>classic openais</value>
 | |
| +                <value>classic openais (with plugin)</value>
 | |
| +                <value>cman</value>
 | |
| +              </choice>
 | |
| +            </except>
 | |
| +          </data>
 | |
| +        </attribute>
 | |
| +      </group>
 | |
| +      <group>
 | |
| +        <attribute name="name">
 | |
| +          <data type="string">
 | |
| +            <except>
 | |
| +              <choice>
 | |
| +                <value>cluster-infrastructure</value>
 | |
| +                <value>cluster_recheck_interval</value>
 | |
| +                <value>dc_deadtime</value>
 | |
| +                <value>default-action-timeout</value>
 | |
| +                <value>default_action_timeout</value>
 | |
| +                <value>default-migration-threshold</value>
 | |
| +                <value>default_migration_threshold</value>
 | |
| +                <value>default-resource-failure-stickiness</value>
 | |
| +                <value>default_resource_failure_stickiness</value>
 | |
| +                <value>default-resource-stickiness</value>
 | |
| +                <value>default_resource_stickiness</value>
 | |
| +                <value>election_timeout</value>
 | |
| +                <value>expected-quorum-votes</value>
 | |
| +                <value>is-managed-default</value>
 | |
| +                <value>is_managed_default</value>
 | |
| +                <value>no_quorum_policy</value>
 | |
| +                <value>notification-agent</value>
 | |
| +                <value>notification-recipient</value>
 | |
| +                <value>remove_after_stop</value>
 | |
| +                <value>shutdown_escalation</value>
 | |
| +                <value>startup_fencing</value>
 | |
| +                <value>stonith_action</value>
 | |
| +                <value>stonith_enabled</value>
 | |
| +                <value>stop_orphan_actions</value>
 | |
| +                <value>stop_orphan_resources</value>
 | |
| +                <value>symmetric_cluster</value>
 | |
| +                <value>transition_idle_timeout</value>
 | |
| +              </choice>
 | |
| +            </except>
 | |
| +          </data>
 | |
| +        </attribute>
 | |
| +        <optional>
 | |
| +          <attribute name="value"><text/></attribute>
 | |
| +        </optional>
 | |
| +      </group>
 | |
| +    </choice>
 | |
| +  </define>
 | |
| +
 | |
| +  <define name="options">
 | |
| +    <interleave>
 | |
| +      <element name="crm_config">
 | |
| +        <zeroOrMore>
 | |
| +          <element name="cluster_property_set">
 | |
| +            <grammar>
 | |
| +              <include href="nvset-3.4.rng">
 | |
| +                <define name="element-nvset.name-value">
 | |
| +                  <parentRef name="cluster_property_set.nvpair.name-value-unsupported"/>
 | |
| +                </define>
 | |
| +              </include>
 | |
| +            </grammar>
 | |
| +          </element>
 | |
| +        </zeroOrMore>
 | |
| +      </element>
 | |
| +      <optional>
 | |
| +        <element name="rsc_defaults">
 | |
| +          <zeroOrMore>
 | |
| +            <element name="meta_attributes">
 | |
| +              <externalRef href="nvset-3.4.rng"/>
 | |
| +            </element>
 | |
| +          </zeroOrMore>
 | |
| +        </element>
 | |
| +      </optional>
 | |
| +      <optional>
 | |
| +        <element name="op_defaults">
 | |
| +          <zeroOrMore>
 | |
| +            <element name="meta_attributes">
 | |
| +              <externalRef href="nvset-3.4.rng"/>
 | |
| +            </element>
 | |
| +          </zeroOrMore>
 | |
| +        </element>
 | |
| +      </optional>
 | |
| +    </interleave>
 | |
| +  </define>
 | |
| +
 | |
| +</grammar>
 | |
| diff --git a/xml/resources-3.4.rng b/xml/resources-3.4.rng
 | |
| new file mode 100644
 | |
| index 0000000..fbb4b65
 | |
| --- /dev/null
 | |
| +++ b/xml/resources-3.4.rng
 | |
| @@ -0,0 +1,425 @@
 | |
| +<?xml version="1.0" encoding="UTF-8"?>
 | |
| +<grammar xmlns="http://relaxng.org/ns/structure/1.0"
 | |
| +         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
 | |
| +  <start>
 | |
| +    <ref name="element-resources"/>
 | |
| +  </start>
 | |
| +
 | |
| +  <define name="element-resources">
 | |
| +    <element name="resources">
 | |
| +      <zeroOrMore>
 | |
| +        <choice>
 | |
| +          <ref name="element-primitive"/>
 | |
| +          <ref name="element-template"/>
 | |
| +          <ref name="element-group"/>
 | |
| +          <ref name="element-clone"/>
 | |
| +          <ref name="element-master"/>
 | |
| +          <ref name="element-bundle"/>
 | |
| +        </choice>
 | |
| +      </zeroOrMore>
 | |
| +    </element>
 | |
| +  </define>
 | |
| +
 | |
| +  <!--
 | |
| +   see upgrade-2.10.xsl
 | |
| +   - cibtr:table for="resource-meta-attributes"
 | |
| +   -->
 | |
| +  <define name="primitive-template.meta_attributes.nvpair.name-unsupported">
 | |
| +    <attribute name="name">
 | |
| +      <data type="string">
 | |
| +        <except>
 | |
| +          <choice>
 | |
| +            <value>isolation</value>
 | |
| +            <value>isolation-host</value>
 | |
| +            <value>isolation-instance</value>
 | |
| +            <value>isolation-wrapper</value>
 | |
| +          </choice>
 | |
| +        </except>
 | |
| +      </data>
 | |
| +    </attribute>
 | |
| +  </define>
 | |
| +
 | |
| +  <define name="element-resource-extra.primitive-template">
 | |
| +    <zeroOrMore>
 | |
| +      <choice>
 | |
| +        <element name="meta_attributes">
 | |
| +          <grammar>
 | |
| +            <include href="nvset-3.4.rng">
 | |
| +              <define name="element-nvset.name">
 | |
| +                <parentRef name="primitive-template.meta_attributes.nvpair.name-unsupported"/>
 | |
| +              </define>
 | |
| +            </include>
 | |
| +          </grammar>
 | |
| +        </element>
 | |
| +        <element name="instance_attributes">
 | |
| +          <externalRef href="nvset-3.4.rng"/>
 | |
| +        </element>
 | |
| +      </choice>
 | |
| +    </zeroOrMore>
 | |
| +  </define>
 | |
| +
 | |
| +  <define name="element-primitive">
 | |
| +    <element name="primitive">
 | |
| +      <interleave>
 | |
| +        <attribute name="id"><data type="ID"/></attribute>
 | |
| +        <choice>
 | |
| +          <group>
 | |
| +            <ref name="element-resource-class"/>
 | |
| +            <attribute name="type"><text/></attribute>
 | |
| +          </group>
 | |
| +          <attribute name="template"><data type="IDREF"/></attribute>
 | |
| +        </choice>
 | |
| +        <optional>
 | |
| +          <attribute name="description"><text/></attribute>
 | |
| +        </optional>
 | |
| +        <ref name="element-resource-extra.primitive-template"/>
 | |
| +        <ref name="element-operations"/>
 | |
| +        <zeroOrMore>
 | |
| +          <element name="utilization">
 | |
| +            <externalRef href="nvset-3.4.rng"/>
 | |
| +          </element>
 | |
| +        </zeroOrMore>
 | |
| +      </interleave>
 | |
| +    </element>
 | |
| +  </define>
 | |
| +
 | |
| +  <define name="element-template">
 | |
| +    <element name="template">
 | |
| +      <interleave>
 | |
| +        <attribute name="id"><data type="ID"/></attribute>
 | |
| +        <ref name="element-resource-class"/>
 | |
| +        <attribute name="type"><text/></attribute>
 | |
| +        <optional>
 | |
| +          <attribute name="description"><text/></attribute>
 | |
| +        </optional>
 | |
| +        <ref name="element-resource-extra.primitive-template"/>
 | |
| +        <ref name="element-operations"/>
 | |
| +        <zeroOrMore>
 | |
| +          <element name="utilization">
 | |
| +            <externalRef href="nvset-3.4.rng"/>
 | |
| +          </element>
 | |
| +        </zeroOrMore>
 | |
| +      </interleave>
 | |
| +    </element>
 | |
| +  </define>
 | |
| +
 | |
| +  <define name="element-bundle">
 | |
| +    <element name="bundle">
 | |
| +      <interleave>
 | |
| +        <attribute name="id"><data type="ID"/></attribute>
 | |
| +        <optional>
 | |
| +          <attribute name="description"><text/></attribute>
 | |
| +        </optional>
 | |
| +        <ref name="element-resource-extra"/>
 | |
| +        <choice>
 | |
| +          <element name="docker">
 | |
| +            <attribute name="image"><text/></attribute>
 | |
| +            <optional>
 | |
| +              <attribute name="replicas"><data type="integer"/></attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="replicas-per-host"><data type="integer"/></attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <choice>
 | |
| +                <attribute name="masters"><data type="integer"/></attribute>
 | |
| +                <attribute name="promoted-max"><data type="integer"/></attribute>
 | |
| +              </choice>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="run-command"> <text/></attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="network"><text/></attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="options"><text/></attribute>
 | |
| +            </optional>
 | |
| +          </element>
 | |
| +          <element name="rkt">
 | |
| +            <attribute name="image"><text/></attribute>
 | |
| +            <optional>
 | |
| +              <attribute name="replicas"><data type="integer"/></attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="replicas-per-host"><data type="integer"/></attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <choice>
 | |
| +                <attribute name="masters"><data type="integer"/></attribute>
 | |
| +                <attribute name="promoted-max"><data type="integer"/></attribute>
 | |
| +              </choice>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="run-command"> <text/></attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="network"><text/></attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="options"><text/></attribute>
 | |
| +            </optional>
 | |
| +          </element>
 | |
| +          <element name="podman">
 | |
| +            <attribute name="image"><text/></attribute>
 | |
| +            <optional>
 | |
| +              <attribute name="replicas"><data type="integer"/></attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="replicas-per-host"><data type="integer"/></attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <choice>
 | |
| +                <attribute name="masters"><data type="integer"/></attribute>
 | |
| +                <attribute name="promoted-max"><data type="integer"/></attribute>
 | |
| +              </choice>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="run-command"> <text/></attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="network"><text/></attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="options"><text/></attribute>
 | |
| +            </optional>
 | |
| +          </element>
 | |
| +        </choice>
 | |
| +        <optional>
 | |
| +          <element name="network">
 | |
| +            <optional>
 | |
| +              <attribute name="ip-range-start"><text/></attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="control-port"><data type="integer"/></attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="host-interface"><text/></attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="host-netmask"><data type="integer"/></attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="add-host"><data type="boolean"/></attribute>
 | |
| +            </optional>
 | |
| +            <zeroOrMore>
 | |
| +              <element name="port-mapping">
 | |
| +                <attribute name="id"><data type="ID"/></attribute>
 | |
| +                <choice>
 | |
| +                  <group>
 | |
| +                    <attribute name="port"><data type="integer"/></attribute>
 | |
| +                    <optional>
 | |
| +                      <attribute name="internal-port"><data type="integer"/></attribute>
 | |
| +                    </optional>
 | |
| +                  </group>
 | |
| +                  <attribute name="range">
 | |
| +                    <data type="string">
 | |
| +                      <param name="pattern">([0-9\-]+)</param>
 | |
| +                    </data>
 | |
| +                  </attribute>
 | |
| +                </choice>
 | |
| +              </element>
 | |
| +            </zeroOrMore>
 | |
| +          </element>
 | |
| +        </optional>
 | |
| +        <optional>
 | |
| +          <element name="storage">
 | |
| +            <zeroOrMore>
 | |
| +              <element name="storage-mapping">
 | |
| +                <attribute name="id"><data type="ID"/></attribute>
 | |
| +                <choice>
 | |
| +                  <attribute name="source-dir"><text/></attribute>
 | |
| +                  <attribute name="source-dir-root"><text/></attribute>
 | |
| +                </choice>
 | |
| +                <attribute name="target-dir"><text/></attribute>
 | |
| +                <optional>
 | |
| +                  <attribute name="options"><text/></attribute>
 | |
| +                </optional>
 | |
| +              </element>
 | |
| +            </zeroOrMore>
 | |
| +          </element>
 | |
| +        </optional>
 | |
| +        <optional>
 | |
| +          <ref name="element-primitive"/>
 | |
| +        </optional>
 | |
| +      </interleave>
 | |
| +    </element>
 | |
| +  </define>
 | |
| +
 | |
| +  <define name="element-group">
 | |
| +    <element name="group">
 | |
| +      <attribute name="id"><data type="ID"/></attribute>
 | |
| +      <optional>
 | |
| +        <attribute name="description"><text/></attribute>
 | |
| +      </optional>
 | |
| +      <interleave>
 | |
| +        <ref name="element-resource-extra"/>
 | |
| +        <oneOrMore>
 | |
| +          <ref name="element-primitive"/>
 | |
| +        </oneOrMore>
 | |
| +      </interleave>
 | |
| +    </element>
 | |
| +  </define>
 | |
| +
 | |
| +  <define name="element-clone">
 | |
| +    <element name="clone">
 | |
| +      <attribute name="id"><data type="ID"/></attribute>
 | |
| +      <optional>
 | |
| +        <attribute name="description"><text/></attribute>
 | |
| +      </optional>
 | |
| +      <interleave>
 | |
| +        <ref name="element-resource-extra"/>
 | |
| +        <choice>
 | |
| +          <ref name="element-primitive"/>
 | |
| +          <ref name="element-group"/>
 | |
| +        </choice>
 | |
| +      </interleave>
 | |
| +    </element>
 | |
| +  </define>
 | |
| +
 | |
| +  <define name="element-master">
 | |
| +    <element name="master">
 | |
| +      <attribute name="id"><data type="ID"/></attribute>
 | |
| +      <optional>
 | |
| +        <attribute name="description"><text/></attribute>
 | |
| +      </optional>
 | |
| +      <interleave>
 | |
| +        <ref name="element-resource-extra"/>
 | |
| +        <choice>
 | |
| +          <ref name="element-primitive"/>
 | |
| +          <ref name="element-group"/>
 | |
| +        </choice>
 | |
| +      </interleave>
 | |
| +    </element>
 | |
| +  </define>
 | |
| +
 | |
| +  <define name="element-resource-extra">
 | |
| +    <zeroOrMore>
 | |
| +      <choice>
 | |
| +        <element name="meta_attributes">
 | |
| +          <externalRef href="nvset-3.4.rng"/>
 | |
| +        </element>
 | |
| +        <element name="instance_attributes">
 | |
| +          <externalRef href="nvset-3.4.rng"/>
 | |
| +        </element>
 | |
| +      </choice>
 | |
| +    </zeroOrMore>
 | |
| +  </define>
 | |
| +
 | |
| +  <!--
 | |
| +   see upgrade-2.10.xsl
 | |
| +   - cibtr:table for="resources-operation"
 | |
| +   -->
 | |
| +  <define name="op.meta_attributes.nvpair.name-unsupported">
 | |
| +    <attribute name="name">
 | |
| +      <data type="string">
 | |
| +        <except>
 | |
| +          <choice>
 | |
| +            <value>requires</value>
 | |
| +          </choice>
 | |
| +        </except>
 | |
| +      </data>
 | |
| +    </attribute>
 | |
| +  </define>
 | |
| +
 | |
| +  <define name="element-resource-extra.op">
 | |
| +    <zeroOrMore>
 | |
| +      <choice>
 | |
| +        <element name="meta_attributes">
 | |
| +          <grammar>
 | |
| +            <include href="nvset-3.4.rng">
 | |
| +              <define name="element-nvset.name">
 | |
| +                <parentRef name="op.meta_attributes.nvpair.name-unsupported"/>
 | |
| +              </define>
 | |
| +            </include>
 | |
| +          </grammar>
 | |
| +        </element>
 | |
| +        <element name="instance_attributes">
 | |
| +          <externalRef href="nvset-3.4.rng"/>
 | |
| +        </element>
 | |
| +      </choice>
 | |
| +    </zeroOrMore>
 | |
| +  </define>
 | |
| +
 | |
| +  <define name="element-operations">
 | |
| +    <optional>
 | |
| +      <element name="operations">
 | |
| +        <optional>
 | |
| +          <attribute name="id"><data type="ID"/></attribute>
 | |
| +        </optional>
 | |
| +        <optional>
 | |
| +          <attribute name="id-ref"><data type="IDREF"/></attribute>
 | |
| +        </optional>
 | |
| +        <zeroOrMore>
 | |
| +          <element name="op">
 | |
| +            <attribute name="id"><data type="ID"/></attribute>
 | |
| +            <attribute name="name"><text/></attribute>
 | |
| +            <attribute name="interval"><text/></attribute>
 | |
| +            <optional>
 | |
| +              <attribute name="description"><text/></attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <choice>
 | |
| +                <attribute name="start-delay"><text/></attribute>
 | |
| +                <attribute name="interval-origin"><text/></attribute>
 | |
| +              </choice>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="timeout"><text/></attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="enabled"><data type="boolean"/></attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="record-pending"><data type="boolean"/></attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="role">
 | |
| +                <choice>
 | |
| +                  <value>Stopped</value>
 | |
| +                  <value>Started</value>
 | |
| +                  <value>Slave</value>
 | |
| +                  <value>Master</value>
 | |
| +                </choice>
 | |
| +              </attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="on-fail">
 | |
| +                <choice>
 | |
| +                  <value>ignore</value>
 | |
| +                  <value>block</value>
 | |
| +                  <value>stop</value>
 | |
| +                  <value>restart</value>
 | |
| +                  <value>standby</value>
 | |
| +                  <value>fence</value>
 | |
| +                  <value>restart-container</value>
 | |
| +                </choice>
 | |
| +              </attribute>
 | |
| +            </optional>
 | |
| +            <ref name="element-resource-extra.op"/>
 | |
| +          </element>
 | |
| +        </zeroOrMore>
 | |
| +      </element>
 | |
| +    </optional>
 | |
| +  </define>
 | |
| +
 | |
| +  <define name="element-resource-class">
 | |
| +    <choice>
 | |
| +      <group>
 | |
| +        <attribute name="class"><value>ocf</value></attribute>
 | |
| +        <attribute name="provider"><text/></attribute>
 | |
| +      </group>
 | |
| +      <attribute name="class">
 | |
| +        <choice>
 | |
| +          <value>lsb</value>
 | |
| +          <value>heartbeat</value>
 | |
| +          <value>stonith</value>
 | |
| +          <value>upstart</value>
 | |
| +          <value>service</value>
 | |
| +          <value>systemd</value>
 | |
| +          <value>nagios</value>
 | |
| +        </choice>
 | |
| +      </attribute>
 | |
| +    </choice>
 | |
| +  </define>
 | |
| +</grammar>
 | |
| diff --git a/xml/rule-3.4.rng b/xml/rule-3.4.rng
 | |
| new file mode 100644
 | |
| index 0000000..5d1daf0
 | |
| --- /dev/null
 | |
| +++ b/xml/rule-3.4.rng
 | |
| @@ -0,0 +1,165 @@
 | |
| +<?xml version="1.0" encoding="UTF-8"?>
 | |
| +<grammar xmlns="http://relaxng.org/ns/structure/1.0" 
 | |
| +         xmlns:ann="http://relaxng.org/ns/compatibility/annotations/1.0"
 | |
| +         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
 | |
| +  <start>
 | |
| +      <ref name="element-rule"/>
 | |
| +  </start>
 | |
| +
 | |
| +  <define name="element-rule">
 | |
| +    <element name="rule">
 | |
| +     <choice>
 | |
| +     <attribute name="id-ref"><data type="IDREF"/></attribute>
 | |
| +     <group>
 | |
| +      <attribute name="id"><data type="ID"/></attribute>
 | |
| +      <choice>
 | |
| +        <externalRef href="score.rng"/>
 | |
| +        <attribute name="score-attribute"><text/></attribute>
 | |
| +      </choice>
 | |
| +      <optional>
 | |
| +        <attribute name="boolean-op">
 | |
| +          <choice>
 | |
| +            <value>or</value>
 | |
| +            <value>and</value>
 | |
| +          </choice>
 | |
| +        </attribute>
 | |
| +      </optional>
 | |
| +      <optional>
 | |
| +        <attribute name="role"><text/></attribute>
 | |
| +      </optional>
 | |
| +      <oneOrMore>
 | |
| +        <choice>
 | |
| +          <element name="expression">
 | |
| +            <attribute name="id"><data type="ID"/></attribute>
 | |
| +            <attribute name="attribute"><text/></attribute>
 | |
| +            <attribute name="operation">
 | |
| +              <choice>
 | |
| +                <value>lt</value>
 | |
| +                <value>gt</value>
 | |
| +                <value>lte</value>
 | |
| +                <value>gte</value>
 | |
| +                <value>eq</value>
 | |
| +                <value>ne</value>
 | |
| +                <value>defined</value>
 | |
| +                <value>not_defined</value>
 | |
| +              </choice>
 | |
| +            </attribute>
 | |
| +            <optional>
 | |
| +              <attribute name="value"><text/></attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="type" ann:defaultValue="string">
 | |
| +                <choice>
 | |
| +                  <value>string</value>
 | |
| +                  <value>number</value>
 | |
| +                  <value>version</value>
 | |
| +                </choice>
 | |
| +              </attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="value-source" ann:defaultValue="literal">
 | |
| +                <choice>
 | |
| +                  <value>literal</value>
 | |
| +                  <value>param</value>
 | |
| +                  <value>meta</value>
 | |
| +                </choice>
 | |
| +              </attribute>
 | |
| +            </optional>
 | |
| +          </element>
 | |
| +          <element name="date_expression">
 | |
| +            <attribute name="id"><data type="ID"/></attribute>
 | |
| +            <choice>
 | |
| +              <group>
 | |
| +                <attribute name="operation"><value>in_range</value></attribute>
 | |
| +                <choice>
 | |
| +                  <group>
 | |
| +                    <optional>
 | |
| +                      <attribute name="start"><text/></attribute>
 | |
| +                    </optional>
 | |
| +                    <attribute name="end"><text/></attribute>
 | |
| +                  </group>
 | |
| +                  <group>
 | |
| +                    <attribute name="start"><text/></attribute>
 | |
| +                    <element name="duration">
 | |
| +                      <ref name="date-common"/>
 | |
| +                    </element>
 | |
| +                  </group>
 | |
| +                </choice>
 | |
| +              </group>
 | |
| +              <group>
 | |
| +                <attribute name="operation"><value>gt</value></attribute>
 | |
| +                <attribute name="start"><text/></attribute>
 | |
| +              </group>
 | |
| +              <group>
 | |
| +                <attribute name="operation"><value>lt</value></attribute>
 | |
| +                <choice>
 | |
| +                  <attribute name="end"><text/></attribute>
 | |
| +                </choice>
 | |
| +              </group>
 | |
| +              <group>
 | |
| +                <attribute name="operation"><value>date_spec</value></attribute>
 | |
| +                <element name="date_spec">
 | |
| +                  <ref name="date-common"/>
 | |
| +                </element> 
 | |
| +              </group>
 | |
| +            </choice>
 | |
| +          </element> 
 | |
| +          <element name="rsc_expression">
 | |
| +            <attribute name="id"><data type="ID"/></attribute>
 | |
| +            <optional>
 | |
| +              <attribute name="class"><text/></attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="provider"><text/></attribute>
 | |
| +            </optional>
 | |
| +            <optional>
 | |
| +              <attribute name="type"><text/></attribute>
 | |
| +            </optional>
 | |
| +          </element>
 | |
| +          <element name="op_expression">
 | |
| +            <attribute name="id"><data type="ID"/></attribute>
 | |
| +            <attribute name="name"><text/></attribute>
 | |
| +            <optional>
 | |
| +              <attribute name="interval"><text/></attribute>
 | |
| +            </optional>
 | |
| +          </element>
 | |
| +          <ref name="element-rule"/>
 | |
| +        </choice>
 | |
| +      </oneOrMore>
 | |
| +     </group>
 | |
| +     </choice>
 | |
| +    </element>
 | |
| +  </define>
 | |
| +
 | |
| +  <define name="date-common">
 | |
| +    <attribute name="id"><data type="ID"/></attribute>
 | |
| +    <optional>
 | |
| +      <attribute name="hours"><text/></attribute>
 | |
| +    </optional>
 | |
| +    <optional>
 | |
| +      <attribute name="monthdays"><text/></attribute>
 | |
| +    </optional>
 | |
| +    <optional>
 | |
| +      <attribute name="weekdays"><text/></attribute>
 | |
| +    </optional>
 | |
| +    <optional>
 | |
| +      <attribute name="yearsdays"><text/></attribute>
 | |
| +    </optional>
 | |
| +    <optional>
 | |
| +      <attribute name="months"><text/></attribute>
 | |
| +    </optional>
 | |
| +    <optional>
 | |
| +      <attribute name="weeks"><text/></attribute>
 | |
| +    </optional>
 | |
| +    <optional>
 | |
| +      <attribute name="years"><text/></attribute>
 | |
| +    </optional>
 | |
| +    <optional>
 | |
| +      <attribute name="weekyears"><text/></attribute>
 | |
| +    </optional>
 | |
| +    <optional>
 | |
| +      <attribute name="moon"><text/></attribute>
 | |
| +    </optional>
 | |
| +  </define>
 | |
| +
 | |
| +</grammar>
 | |
| -- 
 | |
| 1.8.3.1
 | |
| 
 | |
| 
 | |
| From b0e2345d92fb7cf42c133b24457eeb07126db8a0 Mon Sep 17 00:00:00 2001
 | |
| From: Chris Lumens <clumens@redhat.com>
 | |
| Date: Mon, 27 Apr 2020 16:24:22 -0400
 | |
| Subject: [PATCH 11/17] Fix: scheduler: Change trace output in populate_hash.
 | |
| 
 | |
| Only show the "Setting attribute:" text when it comes time to actually
 | |
| set the attribute.  Also show the value being set.  This makes it
 | |
| clearer that an attribute is actually being set, not just that the
 | |
| function is processing something.
 | |
| ---
 | |
|  lib/pengine/rules.c | 3 +--
 | |
|  1 file changed, 1 insertion(+), 2 deletions(-)
 | |
| 
 | |
| diff --git a/lib/pengine/rules.c b/lib/pengine/rules.c
 | |
| index 7575011..b0fca55 100644
 | |
| --- a/lib/pengine/rules.c
 | |
| +++ b/lib/pengine/rules.c
 | |
| @@ -463,7 +463,6 @@ populate_hash(xmlNode * nvpair_list, GHashTable * hash, gboolean overwrite, xmlN
 | |
|                  name = crm_element_value(ref_nvpair, XML_NVPAIR_ATTR_NAME);
 | |
|              }
 | |
|  
 | |
| -            crm_trace("Setting attribute: %s", name);
 | |
|              value = crm_element_value(an_attr, XML_NVPAIR_ATTR_VALUE);
 | |
|              if (value == NULL) {
 | |
|                  value = crm_element_value(ref_nvpair, XML_NVPAIR_ATTR_VALUE);
 | |
| @@ -471,7 +470,6 @@ populate_hash(xmlNode * nvpair_list, GHashTable * hash, gboolean overwrite, xmlN
 | |
|  
 | |
|              if (name == NULL || value == NULL) {
 | |
|                  continue;
 | |
| -
 | |
|              }
 | |
|  
 | |
|              old_value = g_hash_table_lookup(hash, name);
 | |
| @@ -484,6 +482,7 @@ populate_hash(xmlNode * nvpair_list, GHashTable * hash, gboolean overwrite, xmlN
 | |
|                  continue;
 | |
|  
 | |
|              } else if (old_value == NULL) {
 | |
| +                crm_trace("Setting attribute: %s = %s", name, value);
 | |
|                  g_hash_table_insert(hash, strdup(name), strdup(value));
 | |
|  
 | |
|              } else if (overwrite) {
 | |
| -- 
 | |
| 1.8.3.1
 | |
| 
 | |
| 
 | |
| From d35854384b231c79b8aba1ce4c5caf5dd51ec982 Mon Sep 17 00:00:00 2001
 | |
| From: Chris Lumens <clumens@redhat.com>
 | |
| Date: Fri, 1 May 2020 15:45:31 -0400
 | |
| Subject: [PATCH 12/17] Test: scheduler: Add a regression test for op_defaults.
 | |
| 
 | |
| ---
 | |
|  cts/cts-scheduler.in              |   3 +
 | |
|  cts/scheduler/op-defaults.dot     |  33 ++++++
 | |
|  cts/scheduler/op-defaults.exp     | 211 ++++++++++++++++++++++++++++++++++++++
 | |
|  cts/scheduler/op-defaults.scores  |  11 ++
 | |
|  cts/scheduler/op-defaults.summary |  46 +++++++++
 | |
|  cts/scheduler/op-defaults.xml     |  87 ++++++++++++++++
 | |
|  6 files changed, 391 insertions(+)
 | |
|  create mode 100644 cts/scheduler/op-defaults.dot
 | |
|  create mode 100644 cts/scheduler/op-defaults.exp
 | |
|  create mode 100644 cts/scheduler/op-defaults.scores
 | |
|  create mode 100644 cts/scheduler/op-defaults.summary
 | |
|  create mode 100644 cts/scheduler/op-defaults.xml
 | |
| 
 | |
| diff --git a/cts/cts-scheduler.in b/cts/cts-scheduler.in
 | |
| index 5d72205..b83f812 100644
 | |
| --- a/cts/cts-scheduler.in
 | |
| +++ b/cts/cts-scheduler.in
 | |
| @@ -962,6 +962,9 @@ TESTS = [
 | |
|          [ "shutdown-lock", "Ensure shutdown lock works properly" ],
 | |
|          [ "shutdown-lock-expiration", "Ensure shutdown lock expiration works properly" ],
 | |
|      ],
 | |
| +    [
 | |
| +        [ "op-defaults", "Test op_defaults conditional expressions " ],
 | |
| +    ],
 | |
|      
 | |
|      # @TODO: If pacemaker implements versioned attributes, uncomment these tests
 | |
|      #[
 | |
| diff --git a/cts/scheduler/op-defaults.dot b/cts/scheduler/op-defaults.dot
 | |
| new file mode 100644
 | |
| index 0000000..5536c15
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/op-defaults.dot
 | |
| @@ -0,0 +1,33 @@
 | |
| + digraph "g" {
 | |
| +"dummy-rsc_monitor_0 cluster01" -> "dummy-rsc_start_0 cluster02" [ style = bold]
 | |
| +"dummy-rsc_monitor_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"dummy-rsc_monitor_0 cluster02" -> "dummy-rsc_start_0 cluster02" [ style = bold]
 | |
| +"dummy-rsc_monitor_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"dummy-rsc_monitor_60000 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"dummy-rsc_start_0 cluster02" -> "dummy-rsc_monitor_60000 cluster02" [ style = bold]
 | |
| +"dummy-rsc_start_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"fencing_monitor_0 cluster01" -> "fencing_start_0 cluster01" [ style = bold]
 | |
| +"fencing_monitor_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"fencing_monitor_0 cluster02" -> "fencing_start_0 cluster01" [ style = bold]
 | |
| +"fencing_monitor_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"fencing_start_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"ip-rsc2_monitor_0 cluster01" -> "ip-rsc2_start_0 cluster01" [ style = bold]
 | |
| +"ip-rsc2_monitor_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"ip-rsc2_monitor_0 cluster02" -> "ip-rsc2_start_0 cluster01" [ style = bold]
 | |
| +"ip-rsc2_monitor_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"ip-rsc2_monitor_10000 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"ip-rsc2_start_0 cluster01" -> "ip-rsc2_monitor_10000 cluster01" [ style = bold]
 | |
| +"ip-rsc2_start_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"ip-rsc_monitor_0 cluster01" -> "ip-rsc_start_0 cluster02" [ style = bold]
 | |
| +"ip-rsc_monitor_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"ip-rsc_monitor_0 cluster02" -> "ip-rsc_start_0 cluster02" [ style = bold]
 | |
| +"ip-rsc_monitor_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"ip-rsc_monitor_20000 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"ip-rsc_start_0 cluster02" -> "ip-rsc_monitor_20000 cluster02" [ style = bold]
 | |
| +"ip-rsc_start_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"ping-rsc-ping_monitor_0 cluster01" -> "ping-rsc-ping_start_0 cluster01" [ style = bold]
 | |
| +"ping-rsc-ping_monitor_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"ping-rsc-ping_monitor_0 cluster02" -> "ping-rsc-ping_start_0 cluster01" [ style = bold]
 | |
| +"ping-rsc-ping_monitor_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"ping-rsc-ping_start_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +}
 | |
| diff --git a/cts/scheduler/op-defaults.exp b/cts/scheduler/op-defaults.exp
 | |
| new file mode 100644
 | |
| index 0000000..b81eacb
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/op-defaults.exp
 | |
| @@ -0,0 +1,211 @@
 | |
| +<transition_graph cluster-delay="60s" stonith-timeout="60s" failed-stop-offset="INFINITY" failed-start-offset="INFINITY"  transition_id="0">
 | |
| +  <synapse id="0">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="11" operation="start" operation_key="fencing_start_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="fencing" class="stonith" type="fence_xvm"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_timeout="5000"  ip_family="ipv4"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="1" operation="monitor" operation_key="fencing_monitor_0" on_node="cluster01" on_node_uuid="1"/>
 | |
| +      </trigger>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="6" operation="monitor" operation_key="fencing_monitor_0" on_node="cluster02" on_node_uuid="2"/>
 | |
| +      </trigger>
 | |
| +    </inputs>
 | |
| +  </synapse>
 | |
| +  <synapse id="1">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="6" operation="monitor" operation_key="fencing_monitor_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="fencing" class="stonith" type="fence_xvm"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_op_target_rc="7" CRM_meta_timeout="7000"  ip_family="ipv4"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="2">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="1" operation="monitor" operation_key="fencing_monitor_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="fencing" class="stonith" type="fence_xvm"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_op_target_rc="7" CRM_meta_timeout="7000"  ip_family="ipv4"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="3">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="13" operation="monitor" operation_key="ip-rsc_monitor_20000" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="ip-rsc" class="ocf" provider="heartbeat" type="IPaddr2"/>
 | |
| +        <attributes CRM_meta_interval="20000" CRM_meta_name="monitor" CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_timeout="7000" cidr_netmask="32"  ip="172.17.1.1"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="12" operation="start" operation_key="ip-rsc_start_0" on_node="cluster02" on_node_uuid="2"/>
 | |
| +      </trigger>
 | |
| +    </inputs>
 | |
| +  </synapse>
 | |
| +  <synapse id="4">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="12" operation="start" operation_key="ip-rsc_start_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="ip-rsc" class="ocf" provider="heartbeat" type="IPaddr2"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_timeout="5000" cidr_netmask="32"  ip="172.17.1.1"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="2" operation="monitor" operation_key="ip-rsc_monitor_0" on_node="cluster01" on_node_uuid="1"/>
 | |
| +      </trigger>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="7" operation="monitor" operation_key="ip-rsc_monitor_0" on_node="cluster02" on_node_uuid="2"/>
 | |
| +      </trigger>
 | |
| +    </inputs>
 | |
| +  </synapse>
 | |
| +  <synapse id="5">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="7" operation="monitor" operation_key="ip-rsc_monitor_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="ip-rsc" class="ocf" provider="heartbeat" type="IPaddr2"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_op_target_rc="7" CRM_meta_timeout="7000" cidr_netmask="32"  ip="172.17.1.1"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="6">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="2" operation="monitor" operation_key="ip-rsc_monitor_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="ip-rsc" class="ocf" provider="heartbeat" type="IPaddr2"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_op_target_rc="7" CRM_meta_timeout="7000" cidr_netmask="32"  ip="172.17.1.1"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="7">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="15" operation="monitor" operation_key="ip-rsc2_monitor_10000" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="ip-rsc2" class="ocf" provider="heartbeat" type="IPaddr2"/>
 | |
| +        <attributes CRM_meta_interval="10000" CRM_meta_name="monitor" CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_timeout="8000" cidr_netmask="32"  ip="172.17.1.1"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="14" operation="start" operation_key="ip-rsc2_start_0" on_node="cluster01" on_node_uuid="1"/>
 | |
| +      </trigger>
 | |
| +    </inputs>
 | |
| +  </synapse>
 | |
| +  <synapse id="8">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="14" operation="start" operation_key="ip-rsc2_start_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="ip-rsc2" class="ocf" provider="heartbeat" type="IPaddr2"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_timeout="5000" cidr_netmask="32"  ip="172.17.1.1"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="3" operation="monitor" operation_key="ip-rsc2_monitor_0" on_node="cluster01" on_node_uuid="1"/>
 | |
| +      </trigger>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="8" operation="monitor" operation_key="ip-rsc2_monitor_0" on_node="cluster02" on_node_uuid="2"/>
 | |
| +      </trigger>
 | |
| +    </inputs>
 | |
| +  </synapse>
 | |
| +  <synapse id="9">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="8" operation="monitor" operation_key="ip-rsc2_monitor_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="ip-rsc2" class="ocf" provider="heartbeat" type="IPaddr2"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_op_target_rc="7" CRM_meta_timeout="7000" cidr_netmask="32"  ip="172.17.1.1"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="10">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="3" operation="monitor" operation_key="ip-rsc2_monitor_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="ip-rsc2" class="ocf" provider="heartbeat" type="IPaddr2"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_op_target_rc="7" CRM_meta_timeout="7000" cidr_netmask="32"  ip="172.17.1.1"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="11">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="17" operation="monitor" operation_key="dummy-rsc_monitor_60000" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="dummy-rsc" class="ocf" provider="pacemaker" type="Dummy"/>
 | |
| +        <attributes CRM_meta_interval="60000" CRM_meta_name="monitor" CRM_meta_on_fail="stop" CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_timeout="7000"  op_sleep="10"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="16" operation="start" operation_key="dummy-rsc_start_0" on_node="cluster02" on_node_uuid="2"/>
 | |
| +      </trigger>
 | |
| +    </inputs>
 | |
| +  </synapse>
 | |
| +  <synapse id="12">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="16" operation="start" operation_key="dummy-rsc_start_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="dummy-rsc" class="ocf" provider="pacemaker" type="Dummy"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_timeout="6000"  op_sleep="10"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="4" operation="monitor" operation_key="dummy-rsc_monitor_0" on_node="cluster01" on_node_uuid="1"/>
 | |
| +      </trigger>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="9" operation="monitor" operation_key="dummy-rsc_monitor_0" on_node="cluster02" on_node_uuid="2"/>
 | |
| +      </trigger>
 | |
| +    </inputs>
 | |
| +  </synapse>
 | |
| +  <synapse id="13">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="9" operation="monitor" operation_key="dummy-rsc_monitor_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="dummy-rsc" class="ocf" provider="pacemaker" type="Dummy"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_op_target_rc="7" CRM_meta_timeout="7000"  op_sleep="10"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="14">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="4" operation="monitor" operation_key="dummy-rsc_monitor_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="dummy-rsc" class="ocf" provider="pacemaker" type="Dummy"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_op_target_rc="7" CRM_meta_timeout="7000"  op_sleep="10"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="15">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="18" operation="start" operation_key="ping-rsc-ping_start_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="ping-rsc-ping" class="ocf" provider="pacemaker" type="ping"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_timeout="5000"  host_list="4.2.2.2"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="5" operation="monitor" operation_key="ping-rsc-ping_monitor_0" on_node="cluster01" on_node_uuid="1"/>
 | |
| +      </trigger>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="10" operation="monitor" operation_key="ping-rsc-ping_monitor_0" on_node="cluster02" on_node_uuid="2"/>
 | |
| +      </trigger>
 | |
| +    </inputs>
 | |
| +  </synapse>
 | |
| +  <synapse id="16">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="10" operation="monitor" operation_key="ping-rsc-ping_monitor_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="ping-rsc-ping" class="ocf" provider="pacemaker" type="ping"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_op_target_rc="7" CRM_meta_timeout="7000"  host_list="4.2.2.2"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="17">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="5" operation="monitor" operation_key="ping-rsc-ping_monitor_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="ping-rsc-ping" class="ocf" provider="pacemaker" type="ping"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_op_target_rc="7" CRM_meta_timeout="7000"  host_list="4.2.2.2"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +</transition_graph>
 | |
| diff --git a/cts/scheduler/op-defaults.scores b/cts/scheduler/op-defaults.scores
 | |
| new file mode 100644
 | |
| index 0000000..1c622f0
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/op-defaults.scores
 | |
| @@ -0,0 +1,11 @@
 | |
| +Allocation scores:
 | |
| +pcmk__native_allocate: dummy-rsc allocation score on cluster01: 0
 | |
| +pcmk__native_allocate: dummy-rsc allocation score on cluster02: 0
 | |
| +pcmk__native_allocate: fencing allocation score on cluster01: 0
 | |
| +pcmk__native_allocate: fencing allocation score on cluster02: 0
 | |
| +pcmk__native_allocate: ip-rsc allocation score on cluster01: 0
 | |
| +pcmk__native_allocate: ip-rsc allocation score on cluster02: 0
 | |
| +pcmk__native_allocate: ip-rsc2 allocation score on cluster01: 0
 | |
| +pcmk__native_allocate: ip-rsc2 allocation score on cluster02: 0
 | |
| +pcmk__native_allocate: ping-rsc-ping allocation score on cluster01: 0
 | |
| +pcmk__native_allocate: ping-rsc-ping allocation score on cluster02: 0
 | |
| diff --git a/cts/scheduler/op-defaults.summary b/cts/scheduler/op-defaults.summary
 | |
| new file mode 100644
 | |
| index 0000000..b580939
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/op-defaults.summary
 | |
| @@ -0,0 +1,46 @@
 | |
| +
 | |
| +Current cluster status:
 | |
| +Online: [ cluster01 cluster02 ]
 | |
| +
 | |
| + fencing	(stonith:fence_xvm):	 Stopped
 | |
| + ip-rsc	(ocf::heartbeat:IPaddr2):	 Stopped
 | |
| + ip-rsc2	(ocf::heartbeat:IPaddr2):	 Stopped
 | |
| + dummy-rsc	(ocf::pacemaker:Dummy):	 Stopped
 | |
| + ping-rsc-ping	(ocf::pacemaker:ping):	 Stopped
 | |
| +
 | |
| +Transition Summary:
 | |
| + * Start      fencing           ( cluster01 )  
 | |
| + * Start      ip-rsc            ( cluster02 )  
 | |
| + * Start      ip-rsc2           ( cluster01 )  
 | |
| + * Start      dummy-rsc         ( cluster02 )  
 | |
| + * Start      ping-rsc-ping     ( cluster01 )  
 | |
| +
 | |
| +Executing cluster transition:
 | |
| + * Resource action: fencing         monitor on cluster02
 | |
| + * Resource action: fencing         monitor on cluster01
 | |
| + * Resource action: ip-rsc          monitor on cluster02
 | |
| + * Resource action: ip-rsc          monitor on cluster01
 | |
| + * Resource action: ip-rsc2         monitor on cluster02
 | |
| + * Resource action: ip-rsc2         monitor on cluster01
 | |
| + * Resource action: dummy-rsc       monitor on cluster02
 | |
| + * Resource action: dummy-rsc       monitor on cluster01
 | |
| + * Resource action: ping-rsc-ping   monitor on cluster02
 | |
| + * Resource action: ping-rsc-ping   monitor on cluster01
 | |
| + * Resource action: fencing         start on cluster01
 | |
| + * Resource action: ip-rsc          start on cluster02
 | |
| + * Resource action: ip-rsc2         start on cluster01
 | |
| + * Resource action: dummy-rsc       start on cluster02
 | |
| + * Resource action: ping-rsc-ping   start on cluster01
 | |
| + * Resource action: ip-rsc          monitor=20000 on cluster02
 | |
| + * Resource action: ip-rsc2         monitor=10000 on cluster01
 | |
| + * Resource action: dummy-rsc       monitor=60000 on cluster02
 | |
| +
 | |
| +Revised cluster status:
 | |
| +Online: [ cluster01 cluster02 ]
 | |
| +
 | |
| + fencing	(stonith:fence_xvm):	 Started cluster01
 | |
| + ip-rsc	(ocf::heartbeat:IPaddr2):	 Started cluster02
 | |
| + ip-rsc2	(ocf::heartbeat:IPaddr2):	 Started cluster01
 | |
| + dummy-rsc	(ocf::pacemaker:Dummy):	 Started cluster02
 | |
| + ping-rsc-ping	(ocf::pacemaker:ping):	 Started cluster01
 | |
| +
 | |
| diff --git a/cts/scheduler/op-defaults.xml b/cts/scheduler/op-defaults.xml
 | |
| new file mode 100644
 | |
| index 0000000..ae3b248
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/op-defaults.xml
 | |
| @@ -0,0 +1,87 @@
 | |
| +<cib crm_feature_set="3.3.0" validate-with="pacemaker-3.4" epoch="130" num_updates="31" admin_epoch="1" cib-last-written="Fri Apr 24 16:08:36 2020" update-origin="cluster01" update-client="crmd" update-user="hacluster" have-quorum="1" dc-uuid="1">
 | |
| +  <configuration>
 | |
| +    <crm_config>
 | |
| +      <cluster_property_set id="cib-bootstrap-options">
 | |
| +        <nvpair id="cib-bootstrap-options-have-watchdog" name="have-watchdog" value="false"/>
 | |
| +        <nvpair id="cib-bootstrap-options-dc-version" name="dc-version" value="2.0.3-1.c40fb040a.git.el7-c40fb040a"/>
 | |
| +        <nvpair id="cib-bootstrap-options-cluster-infrastructure" name="cluster-infrastructure" value="corosync"/>
 | |
| +        <nvpair id="cib-bootstrap-options-cluster-name" name="cluster-name" value="test-cluster"/>
 | |
| +        <nvpair id="cib-bootstrap-options-stonith-enabled" name="stonith-enabled" value="true"/>
 | |
| +        <nvpair id="cib-bootstrap-options-maintenance-mode" name="maintenance-mode" value="false"/>
 | |
| +      </cluster_property_set>
 | |
| +    </crm_config>
 | |
| +    <nodes>
 | |
| +      <node id="1" uname="cluster01"/>
 | |
| +      <node id="2" uname="cluster02"/>
 | |
| +    </nodes>
 | |
| +    <resources>
 | |
| +      <primitive class="stonith" id="fencing" type="fence_xvm">
 | |
| +        <instance_attributes id="fencing-instance_attributes">
 | |
| +          <nvpair id="fencing-instance_attributes-ip_family" name="ip_family" value="ipv4"/>
 | |
| +        </instance_attributes>
 | |
| +        <operations/>
 | |
| +      </primitive>
 | |
| +      <primitive class="ocf" id="ip-rsc" provider="heartbeat" type="IPaddr2">
 | |
| +        <instance_attributes id="ip-rsc-instance_attributes">
 | |
| +          <nvpair id="ip-rsc-instance_attributes-cidr_netmask" name="cidr_netmask" value="32"/>
 | |
| +          <nvpair id="ip-rsc-instance_attributes-ip" name="ip" value="172.17.1.1"/>
 | |
| +        </instance_attributes>
 | |
| +        <operations>
 | |
| +          <op id="ip-rsc-monitor-interval-20s" interval="20s" name="monitor"/>
 | |
| +        </operations>
 | |
| +      </primitive>
 | |
| +      <primitive class="ocf" id="ip-rsc2" provider="heartbeat" type="IPaddr2">
 | |
| +        <instance_attributes id="ip-rsc2-instance_attributes">
 | |
| +          <nvpair id="ip-rsc2-instance_attributes-cidr_netmask" name="cidr_netmask" value="32"/>
 | |
| +          <nvpair id="ip-rsc2-instance_attributes-ip" name="ip" value="172.17.1.1"/>
 | |
| +        </instance_attributes>
 | |
| +        <operations>
 | |
| +          <op id="ip-rsc2-monitor-interval-10s" interval="10s" name="monitor"/>
 | |
| +        </operations>
 | |
| +      </primitive>
 | |
| +      <primitive class="ocf" id="dummy-rsc" provider="pacemaker" type="Dummy">
 | |
| +        <instance_attributes id="dummy-rsc-instance_attributes">
 | |
| +          <nvpair id="dummy-rsc-instance_attributes-op_sleep" name="op_sleep" value="10"/>
 | |
| +        </instance_attributes>
 | |
| +        <operations>
 | |
| +          <op id="dummy-rsc-monitor-interval-60s" interval="60s" name="monitor" on-fail="stop"/>
 | |
| +        </operations>
 | |
| +      </primitive>
 | |
| +      <primitive class="ocf" id="ping-rsc-ping" provider="pacemaker" type="ping">
 | |
| +        <instance_attributes id="ping-rsc-instance_attributes">
 | |
| +          <nvpair id="ping-rsc-host_list" name="host_list" value="4.2.2.2"/>
 | |
| +        </instance_attributes>
 | |
| +        <operations/>
 | |
| +      </primitive>
 | |
| +    </resources>
 | |
| +    <constraints/>
 | |
| +    <tags/>
 | |
| +    <op_defaults>
 | |
| +      <meta_attributes id="op-defaults">
 | |
| +        <nvpair id="op-defaults-timeout" name="timeout" value="5s"/>
 | |
| +      </meta_attributes>
 | |
| +      <meta_attributes id="op-dummy-defaults">
 | |
| +        <rule id="op-dummy-default-rule" score="INFINITY">
 | |
| +          <rsc_expression id="op-dummy-default-expr" class="ocf" provider="pacemaker" type="Dummy"/>
 | |
| +        </rule>
 | |
| +        <nvpair id="op-dummy-timeout" name="timeout" value="6s"/>
 | |
| +      </meta_attributes>
 | |
| +      <meta_attributes id="op-monitor-defaults">
 | |
| +        <rule id="op-monitor-default-rule" score="INFINITY">
 | |
| +          <op_expression id="op-monitor-default-expr" name="monitor"/>
 | |
| +        </rule>
 | |
| +        <nvpair id="op-monitor-timeout" name="timeout" value="7s"/>
 | |
| +      </meta_attributes>
 | |
| +      <meta_attributes id="op-monitor-interval-defaults">
 | |
| +        <rule id="op-monitor-interval-default-rule" score="INFINITY">
 | |
| +          <op_expression id="op-monitor-interval-default-expr" name="monitor" interval="10s"/>
 | |
| +        </rule>
 | |
| +        <nvpair id="op-monitor-interval-timeout" name="timeout" value="8s"/>
 | |
| +      </meta_attributes>
 | |
| +    </op_defaults>
 | |
| +  </configuration>
 | |
| +  <status>
 | |
| +    <node_state id="1" uname="cluster01" in_ccm="true" crmd="online" crm-debug-origin="do_state_transition" join="member" expected="member"/>
 | |
| +    <node_state id="2" uname="cluster02" in_ccm="true" crmd="online" crm-debug-origin="do_update_resource" join="member" expected="member"/>
 | |
| +  </status>
 | |
| +</cib>
 | |
| -- 
 | |
| 1.8.3.1
 | |
| 
 | |
| 
 | |
| From 67067927bc1b8e000c06d2b5a4ae6b9223ca13c7 Mon Sep 17 00:00:00 2001
 | |
| From: Chris Lumens <clumens@redhat.com>
 | |
| Date: Wed, 13 May 2020 10:40:34 -0400
 | |
| Subject: [PATCH 13/17] Test: scheduler: Add a regression test for
 | |
|  rsc_defaults.
 | |
| 
 | |
| ---
 | |
|  cts/cts-scheduler.in               |   3 +-
 | |
|  cts/scheduler/rsc-defaults.dot     |  18 ++++++
 | |
|  cts/scheduler/rsc-defaults.exp     | 124 +++++++++++++++++++++++++++++++++++++
 | |
|  cts/scheduler/rsc-defaults.scores  |  11 ++++
 | |
|  cts/scheduler/rsc-defaults.summary |  38 ++++++++++++
 | |
|  cts/scheduler/rsc-defaults.xml     |  78 +++++++++++++++++++++++
 | |
|  6 files changed, 271 insertions(+), 1 deletion(-)
 | |
|  create mode 100644 cts/scheduler/rsc-defaults.dot
 | |
|  create mode 100644 cts/scheduler/rsc-defaults.exp
 | |
|  create mode 100644 cts/scheduler/rsc-defaults.scores
 | |
|  create mode 100644 cts/scheduler/rsc-defaults.summary
 | |
|  create mode 100644 cts/scheduler/rsc-defaults.xml
 | |
| 
 | |
| diff --git a/cts/cts-scheduler.in b/cts/cts-scheduler.in
 | |
| index b83f812..9022ce9 100644
 | |
| --- a/cts/cts-scheduler.in
 | |
| +++ b/cts/cts-scheduler.in
 | |
| @@ -963,7 +963,8 @@ TESTS = [
 | |
|          [ "shutdown-lock-expiration", "Ensure shutdown lock expiration works properly" ],
 | |
|      ],
 | |
|      [
 | |
| -        [ "op-defaults", "Test op_defaults conditional expressions " ],
 | |
| +        [ "op-defaults", "Test op_defaults conditional expressions" ],
 | |
| +        [ "rsc-defaults", "Test rsc_defaults conditional expressions" ],
 | |
|      ],
 | |
|      
 | |
|      # @TODO: If pacemaker implements versioned attributes, uncomment these tests
 | |
| diff --git a/cts/scheduler/rsc-defaults.dot b/cts/scheduler/rsc-defaults.dot
 | |
| new file mode 100644
 | |
| index 0000000..d776614
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/rsc-defaults.dot
 | |
| @@ -0,0 +1,18 @@
 | |
| + digraph "g" {
 | |
| +"dummy-rsc_monitor_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"dummy-rsc_monitor_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"fencing_monitor_0 cluster01" -> "fencing_start_0 cluster01" [ style = bold]
 | |
| +"fencing_monitor_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"fencing_monitor_0 cluster02" -> "fencing_start_0 cluster01" [ style = bold]
 | |
| +"fencing_monitor_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"fencing_start_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"ip-rsc2_monitor_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"ip-rsc2_monitor_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"ip-rsc_monitor_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"ip-rsc_monitor_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"ping-rsc-ping_monitor_0 cluster01" -> "ping-rsc-ping_start_0 cluster02" [ style = bold]
 | |
| +"ping-rsc-ping_monitor_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"ping-rsc-ping_monitor_0 cluster02" -> "ping-rsc-ping_start_0 cluster02" [ style = bold]
 | |
| +"ping-rsc-ping_monitor_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"ping-rsc-ping_start_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +}
 | |
| diff --git a/cts/scheduler/rsc-defaults.exp b/cts/scheduler/rsc-defaults.exp
 | |
| new file mode 100644
 | |
| index 0000000..4aec360
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/rsc-defaults.exp
 | |
| @@ -0,0 +1,124 @@
 | |
| +<transition_graph cluster-delay="60s" stonith-timeout="60s" failed-stop-offset="INFINITY" failed-start-offset="INFINITY"  transition_id="0">
 | |
| +  <synapse id="0">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="11" operation="start" operation_key="fencing_start_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="fencing" class="stonith" type="fence_xvm"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_timeout="20000"  ip_family="ipv4"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="1" operation="monitor" operation_key="fencing_monitor_0" on_node="cluster01" on_node_uuid="1"/>
 | |
| +      </trigger>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="6" operation="monitor" operation_key="fencing_monitor_0" on_node="cluster02" on_node_uuid="2"/>
 | |
| +      </trigger>
 | |
| +    </inputs>
 | |
| +  </synapse>
 | |
| +  <synapse id="1">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="6" operation="monitor" operation_key="fencing_monitor_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="fencing" class="stonith" type="fence_xvm"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000"  ip_family="ipv4"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="2">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="1" operation="monitor" operation_key="fencing_monitor_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="fencing" class="stonith" type="fence_xvm"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000"  ip_family="ipv4"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="3">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="7" operation="monitor" operation_key="ip-rsc_monitor_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="ip-rsc" class="ocf" provider="heartbeat" type="IPaddr2"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000" cidr_netmask="32"  ip="172.17.1.1"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="4">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="2" operation="monitor" operation_key="ip-rsc_monitor_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="ip-rsc" class="ocf" provider="heartbeat" type="IPaddr2"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000" cidr_netmask="32"  ip="172.17.1.1"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="5">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="8" operation="monitor" operation_key="ip-rsc2_monitor_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="ip-rsc2" class="ocf" provider="heartbeat" type="IPaddr2"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000" cidr_netmask="32"  ip="172.17.1.1"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="6">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="3" operation="monitor" operation_key="ip-rsc2_monitor_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="ip-rsc2" class="ocf" provider="heartbeat" type="IPaddr2"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000" cidr_netmask="32"  ip="172.17.1.1"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="7">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="9" operation="monitor" operation_key="dummy-rsc_monitor_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="dummy-rsc" class="ocf" provider="pacemaker" type="Dummy"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000"  op_sleep="10"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="8">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="4" operation="monitor" operation_key="dummy-rsc_monitor_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="dummy-rsc" class="ocf" provider="pacemaker" type="Dummy"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000"  op_sleep="10"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="9">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="14" operation="start" operation_key="ping-rsc-ping_start_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="ping-rsc-ping" class="ocf" provider="pacemaker" type="ping"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_timeout="20000"  host_list="4.2.2.2"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="5" operation="monitor" operation_key="ping-rsc-ping_monitor_0" on_node="cluster01" on_node_uuid="1"/>
 | |
| +      </trigger>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="10" operation="monitor" operation_key="ping-rsc-ping_monitor_0" on_node="cluster02" on_node_uuid="2"/>
 | |
| +      </trigger>
 | |
| +    </inputs>
 | |
| +  </synapse>
 | |
| +  <synapse id="10">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="10" operation="monitor" operation_key="ping-rsc-ping_monitor_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="ping-rsc-ping" class="ocf" provider="pacemaker" type="ping"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000"  host_list="4.2.2.2"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="11">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="5" operation="monitor" operation_key="ping-rsc-ping_monitor_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="ping-rsc-ping" class="ocf" provider="pacemaker" type="ping"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000"  host_list="4.2.2.2"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +</transition_graph>
 | |
| diff --git a/cts/scheduler/rsc-defaults.scores b/cts/scheduler/rsc-defaults.scores
 | |
| new file mode 100644
 | |
| index 0000000..e7f1bab
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/rsc-defaults.scores
 | |
| @@ -0,0 +1,11 @@
 | |
| +Allocation scores:
 | |
| +pcmk__native_allocate: dummy-rsc allocation score on cluster01: 0
 | |
| +pcmk__native_allocate: dummy-rsc allocation score on cluster02: 0
 | |
| +pcmk__native_allocate: fencing allocation score on cluster01: 0
 | |
| +pcmk__native_allocate: fencing allocation score on cluster02: 0
 | |
| +pcmk__native_allocate: ip-rsc allocation score on cluster01: -INFINITY
 | |
| +pcmk__native_allocate: ip-rsc allocation score on cluster02: -INFINITY
 | |
| +pcmk__native_allocate: ip-rsc2 allocation score on cluster01: -INFINITY
 | |
| +pcmk__native_allocate: ip-rsc2 allocation score on cluster02: -INFINITY
 | |
| +pcmk__native_allocate: ping-rsc-ping allocation score on cluster01: 0
 | |
| +pcmk__native_allocate: ping-rsc-ping allocation score on cluster02: 0
 | |
| diff --git a/cts/scheduler/rsc-defaults.summary b/cts/scheduler/rsc-defaults.summary
 | |
| new file mode 100644
 | |
| index 0000000..0066f2e
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/rsc-defaults.summary
 | |
| @@ -0,0 +1,38 @@
 | |
| +2 of 5 resource instances DISABLED and 0 BLOCKED from further action due to failure
 | |
| +
 | |
| +Current cluster status:
 | |
| +Online: [ cluster01 cluster02 ]
 | |
| +
 | |
| + fencing	(stonith:fence_xvm):	 Stopped
 | |
| + ip-rsc	(ocf::heartbeat:IPaddr2):	 Stopped (disabled)
 | |
| + ip-rsc2	(ocf::heartbeat:IPaddr2):	 Stopped (disabled)
 | |
| + dummy-rsc	(ocf::pacemaker:Dummy):	 Stopped (unmanaged)
 | |
| + ping-rsc-ping	(ocf::pacemaker:ping):	 Stopped
 | |
| +
 | |
| +Transition Summary:
 | |
| + * Start      fencing           ( cluster01 )  
 | |
| + * Start      ping-rsc-ping     ( cluster02 )  
 | |
| +
 | |
| +Executing cluster transition:
 | |
| + * Resource action: fencing         monitor on cluster02
 | |
| + * Resource action: fencing         monitor on cluster01
 | |
| + * Resource action: ip-rsc          monitor on cluster02
 | |
| + * Resource action: ip-rsc          monitor on cluster01
 | |
| + * Resource action: ip-rsc2         monitor on cluster02
 | |
| + * Resource action: ip-rsc2         monitor on cluster01
 | |
| + * Resource action: dummy-rsc       monitor on cluster02
 | |
| + * Resource action: dummy-rsc       monitor on cluster01
 | |
| + * Resource action: ping-rsc-ping   monitor on cluster02
 | |
| + * Resource action: ping-rsc-ping   monitor on cluster01
 | |
| + * Resource action: fencing         start on cluster01
 | |
| + * Resource action: ping-rsc-ping   start on cluster02
 | |
| +
 | |
| +Revised cluster status:
 | |
| +Online: [ cluster01 cluster02 ]
 | |
| +
 | |
| + fencing	(stonith:fence_xvm):	 Started cluster01
 | |
| + ip-rsc	(ocf::heartbeat:IPaddr2):	 Stopped (disabled)
 | |
| + ip-rsc2	(ocf::heartbeat:IPaddr2):	 Stopped (disabled)
 | |
| + dummy-rsc	(ocf::pacemaker:Dummy):	 Stopped (unmanaged)
 | |
| + ping-rsc-ping	(ocf::pacemaker:ping):	 Started cluster02
 | |
| +
 | |
| diff --git a/cts/scheduler/rsc-defaults.xml b/cts/scheduler/rsc-defaults.xml
 | |
| new file mode 100644
 | |
| index 0000000..38cae8b
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/rsc-defaults.xml
 | |
| @@ -0,0 +1,78 @@
 | |
| +<cib crm_feature_set="3.3.0" validate-with="pacemaker-3.4" epoch="130" num_updates="31" admin_epoch="1" cib-last-written="Fri Apr 24 16:08:36 2020" update-origin="cluster01" update-client="crmd" update-user="hacluster" have-quorum="1" dc-uuid="1">
 | |
| +  <configuration>
 | |
| +    <crm_config>
 | |
| +      <cluster_property_set id="cib-bootstrap-options">
 | |
| +        <nvpair id="cib-bootstrap-options-have-watchdog" name="have-watchdog" value="false"/>
 | |
| +        <nvpair id="cib-bootstrap-options-dc-version" name="dc-version" value="2.0.3-1.c40fb040a.git.el7-c40fb040a"/>
 | |
| +        <nvpair id="cib-bootstrap-options-cluster-infrastructure" name="cluster-infrastructure" value="corosync"/>
 | |
| +        <nvpair id="cib-bootstrap-options-cluster-name" name="cluster-name" value="test-cluster"/>
 | |
| +        <nvpair id="cib-bootstrap-options-stonith-enabled" name="stonith-enabled" value="true"/>
 | |
| +        <nvpair id="cib-bootstrap-options-maintenance-mode" name="maintenance-mode" value="false"/>
 | |
| +      </cluster_property_set>
 | |
| +    </crm_config>
 | |
| +    <nodes>
 | |
| +      <node id="1" uname="cluster01"/>
 | |
| +      <node id="2" uname="cluster02"/>
 | |
| +    </nodes>
 | |
| +    <resources>
 | |
| +      <primitive class="stonith" id="fencing" type="fence_xvm">
 | |
| +        <instance_attributes id="fencing-instance_attributes">
 | |
| +          <nvpair id="fencing-instance_attributes-ip_family" name="ip_family" value="ipv4"/>
 | |
| +        </instance_attributes>
 | |
| +        <operations/>
 | |
| +      </primitive>
 | |
| +      <primitive class="ocf" id="ip-rsc" provider="heartbeat" type="IPaddr2">
 | |
| +        <instance_attributes id="ip-rsc-instance_attributes">
 | |
| +          <nvpair id="ip-rsc-instance_attributes-cidr_netmask" name="cidr_netmask" value="32"/>
 | |
| +          <nvpair id="ip-rsc-instance_attributes-ip" name="ip" value="172.17.1.1"/>
 | |
| +        </instance_attributes>
 | |
| +        <operations>
 | |
| +          <op id="ip-rsc-monitor-interval-20s" interval="20s" name="monitor"/>
 | |
| +        </operations>
 | |
| +      </primitive>
 | |
| +      <primitive class="ocf" id="ip-rsc2" provider="heartbeat" type="IPaddr2">
 | |
| +        <instance_attributes id="ip-rsc2-instance_attributes">
 | |
| +          <nvpair id="ip-rsc2-instance_attributes-cidr_netmask" name="cidr_netmask" value="32"/>
 | |
| +          <nvpair id="ip-rsc2-instance_attributes-ip" name="ip" value="172.17.1.1"/>
 | |
| +        </instance_attributes>
 | |
| +        <operations>
 | |
| +          <op id="ip-rsc2-monitor-interval-10s" interval="10s" name="monitor"/>
 | |
| +        </operations>
 | |
| +      </primitive>
 | |
| +      <primitive class="ocf" id="dummy-rsc" provider="pacemaker" type="Dummy">
 | |
| +        <instance_attributes id="dummy-rsc-instance_attributes">
 | |
| +          <nvpair id="dummy-rsc-instance_attributes-op_sleep" name="op_sleep" value="10"/>
 | |
| +        </instance_attributes>
 | |
| +        <operations>
 | |
| +          <op id="dummy-rsc-monitor-interval-60s" interval="60s" name="monitor" on-fail="stop"/>
 | |
| +        </operations>
 | |
| +      </primitive>
 | |
| +      <primitive class="ocf" id="ping-rsc-ping" provider="pacemaker" type="ping">
 | |
| +        <instance_attributes id="ping-rsc-instance_attributes">
 | |
| +          <nvpair id="ping-rsc-host_list" name="host_list" value="4.2.2.2"/>
 | |
| +        </instance_attributes>
 | |
| +        <operations/>
 | |
| +      </primitive>
 | |
| +    </resources>
 | |
| +    <constraints/>
 | |
| +    <tags/>
 | |
| +    <rsc_defaults>
 | |
| +      <meta_attributes id="op-unmanaged">
 | |
| +        <rule id="op-unmanaged-rule" score="INFINITY">
 | |
| +          <rsc_expression id="op-unmanaged-expr" class="ocf" provider="pacemaker" type="Dummy"/>
 | |
| +        </rule>
 | |
| +        <nvpair id="op-unmanaged-nvpair" name="is-managed" value="false"/>
 | |
| +      </meta_attributes>
 | |
| +      <meta_attributes id="op-target-role">
 | |
| +        <rule id="op-target-role-rule" score="INFINITY">
 | |
| +          <rsc_expression id="op-target-role-expr" class="ocf" provider="heartbeat" type="IPaddr2"/>
 | |
| +        </rule>
 | |
| +        <nvpair id="op-target-role-nvpair" name="target-role" value="Stopped"/>
 | |
| +      </meta_attributes>
 | |
| +    </rsc_defaults>
 | |
| +  </configuration>
 | |
| +  <status>
 | |
| +    <node_state id="1" uname="cluster01" in_ccm="true" crmd="online" crm-debug-origin="do_state_transition" join="member" expected="member"/>
 | |
| +    <node_state id="2" uname="cluster02" in_ccm="true" crmd="online" crm-debug-origin="do_update_resource" join="member" expected="member"/>
 | |
| +  </status>
 | |
| +</cib>
 | |
| -- 
 | |
| 1.8.3.1
 | |
| 
 | |
| 
 | |
| From bcfe068ccb3f3cb6cc3509257fbc4a59bc2b1a41 Mon Sep 17 00:00:00 2001
 | |
| From: Chris Lumens <clumens@redhat.com>
 | |
| Date: Wed, 13 May 2020 12:47:35 -0400
 | |
| Subject: [PATCH 14/17] Test: scheduler: Add a regression test for op_defaults
 | |
|  with an AND expr.
 | |
| 
 | |
| ---
 | |
|  cts/cts-scheduler.in                |   1 +
 | |
|  cts/scheduler/op-defaults-2.dot     |  33 ++++++
 | |
|  cts/scheduler/op-defaults-2.exp     | 211 ++++++++++++++++++++++++++++++++++++
 | |
|  cts/scheduler/op-defaults-2.scores  |  11 ++
 | |
|  cts/scheduler/op-defaults-2.summary |  46 ++++++++
 | |
|  cts/scheduler/op-defaults-2.xml     |  73 +++++++++++++
 | |
|  6 files changed, 375 insertions(+)
 | |
|  create mode 100644 cts/scheduler/op-defaults-2.dot
 | |
|  create mode 100644 cts/scheduler/op-defaults-2.exp
 | |
|  create mode 100644 cts/scheduler/op-defaults-2.scores
 | |
|  create mode 100644 cts/scheduler/op-defaults-2.summary
 | |
|  create mode 100644 cts/scheduler/op-defaults-2.xml
 | |
| 
 | |
| diff --git a/cts/cts-scheduler.in b/cts/cts-scheduler.in
 | |
| index 9022ce9..669b344 100644
 | |
| --- a/cts/cts-scheduler.in
 | |
| +++ b/cts/cts-scheduler.in
 | |
| @@ -964,6 +964,7 @@ TESTS = [
 | |
|      ],
 | |
|      [
 | |
|          [ "op-defaults", "Test op_defaults conditional expressions" ],
 | |
| +        [ "op-defaults-2", "Test op_defaults AND'ed conditional expressions" ],
 | |
|          [ "rsc-defaults", "Test rsc_defaults conditional expressions" ],
 | |
|      ],
 | |
|      
 | |
| diff --git a/cts/scheduler/op-defaults-2.dot b/cts/scheduler/op-defaults-2.dot
 | |
| new file mode 100644
 | |
| index 0000000..5c67bd8
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/op-defaults-2.dot
 | |
| @@ -0,0 +1,33 @@
 | |
| + digraph "g" {
 | |
| +"dummy-rsc_monitor_0 cluster01" -> "dummy-rsc_start_0 cluster02" [ style = bold]
 | |
| +"dummy-rsc_monitor_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"dummy-rsc_monitor_0 cluster02" -> "dummy-rsc_start_0 cluster02" [ style = bold]
 | |
| +"dummy-rsc_monitor_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"dummy-rsc_monitor_10000 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"dummy-rsc_start_0 cluster02" -> "dummy-rsc_monitor_10000 cluster02" [ style = bold]
 | |
| +"dummy-rsc_start_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"fencing_monitor_0 cluster01" -> "fencing_start_0 cluster01" [ style = bold]
 | |
| +"fencing_monitor_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"fencing_monitor_0 cluster02" -> "fencing_start_0 cluster01" [ style = bold]
 | |
| +"fencing_monitor_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"fencing_start_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"ip-rsc_monitor_0 cluster01" -> "ip-rsc_start_0 cluster02" [ style = bold]
 | |
| +"ip-rsc_monitor_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"ip-rsc_monitor_0 cluster02" -> "ip-rsc_start_0 cluster02" [ style = bold]
 | |
| +"ip-rsc_monitor_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"ip-rsc_monitor_20000 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"ip-rsc_start_0 cluster02" -> "ip-rsc_monitor_20000 cluster02" [ style = bold]
 | |
| +"ip-rsc_start_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"ping-rsc-ping_monitor_0 cluster01" -> "ping-rsc-ping_start_0 cluster01" [ style = bold]
 | |
| +"ping-rsc-ping_monitor_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"ping-rsc-ping_monitor_0 cluster02" -> "ping-rsc-ping_start_0 cluster01" [ style = bold]
 | |
| +"ping-rsc-ping_monitor_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"ping-rsc-ping_start_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"rsc-passes_monitor_0 cluster01" -> "rsc-passes_start_0 cluster01" [ style = bold]
 | |
| +"rsc-passes_monitor_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"rsc-passes_monitor_0 cluster02" -> "rsc-passes_start_0 cluster01" [ style = bold]
 | |
| +"rsc-passes_monitor_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"rsc-passes_monitor_10000 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"rsc-passes_start_0 cluster01" -> "rsc-passes_monitor_10000 cluster01" [ style = bold]
 | |
| +"rsc-passes_start_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +}
 | |
| diff --git a/cts/scheduler/op-defaults-2.exp b/cts/scheduler/op-defaults-2.exp
 | |
| new file mode 100644
 | |
| index 0000000..4324fde
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/op-defaults-2.exp
 | |
| @@ -0,0 +1,211 @@
 | |
| +<transition_graph cluster-delay="60s" stonith-timeout="60s" failed-stop-offset="INFINITY" failed-start-offset="INFINITY"  transition_id="0">
 | |
| +  <synapse id="0">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="11" operation="start" operation_key="fencing_start_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="fencing" class="stonith" type="fence_xvm"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_timeout="20000"  ip_family="ipv4"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="1" operation="monitor" operation_key="fencing_monitor_0" on_node="cluster01" on_node_uuid="1"/>
 | |
| +      </trigger>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="6" operation="monitor" operation_key="fencing_monitor_0" on_node="cluster02" on_node_uuid="2"/>
 | |
| +      </trigger>
 | |
| +    </inputs>
 | |
| +  </synapse>
 | |
| +  <synapse id="1">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="6" operation="monitor" operation_key="fencing_monitor_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="fencing" class="stonith" type="fence_xvm"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000"  ip_family="ipv4"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="2">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="1" operation="monitor" operation_key="fencing_monitor_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="fencing" class="stonith" type="fence_xvm"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000"  ip_family="ipv4"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="3">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="13" operation="monitor" operation_key="ip-rsc_monitor_20000" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="ip-rsc" class="ocf" provider="heartbeat" type="IPaddr2"/>
 | |
| +        <attributes CRM_meta_interval="20000" CRM_meta_name="monitor" CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_timeout="20000" cidr_netmask="32"  ip="172.17.1.1"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="12" operation="start" operation_key="ip-rsc_start_0" on_node="cluster02" on_node_uuid="2"/>
 | |
| +      </trigger>
 | |
| +    </inputs>
 | |
| +  </synapse>
 | |
| +  <synapse id="4">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="12" operation="start" operation_key="ip-rsc_start_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="ip-rsc" class="ocf" provider="heartbeat" type="IPaddr2"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_timeout="20000" cidr_netmask="32"  ip="172.17.1.1"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="2" operation="monitor" operation_key="ip-rsc_monitor_0" on_node="cluster01" on_node_uuid="1"/>
 | |
| +      </trigger>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="7" operation="monitor" operation_key="ip-rsc_monitor_0" on_node="cluster02" on_node_uuid="2"/>
 | |
| +      </trigger>
 | |
| +    </inputs>
 | |
| +  </synapse>
 | |
| +  <synapse id="5">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="7" operation="monitor" operation_key="ip-rsc_monitor_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="ip-rsc" class="ocf" provider="heartbeat" type="IPaddr2"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000" cidr_netmask="32"  ip="172.17.1.1"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="6">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="2" operation="monitor" operation_key="ip-rsc_monitor_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="ip-rsc" class="ocf" provider="heartbeat" type="IPaddr2"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000" cidr_netmask="32"  ip="172.17.1.1"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="7">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="15" operation="monitor" operation_key="rsc-passes_monitor_10000" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="rsc-passes" class="ocf" provider="heartbeat" type="IPaddr2"/>
 | |
| +        <attributes CRM_meta_interval="10000" CRM_meta_name="monitor" CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_timeout="8000" cidr_netmask="32"  ip="172.17.1.1"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="14" operation="start" operation_key="rsc-passes_start_0" on_node="cluster01" on_node_uuid="1"/>
 | |
| +      </trigger>
 | |
| +    </inputs>
 | |
| +  </synapse>
 | |
| +  <synapse id="8">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="14" operation="start" operation_key="rsc-passes_start_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="rsc-passes" class="ocf" provider="heartbeat" type="IPaddr2"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_timeout="20000" cidr_netmask="32"  ip="172.17.1.1"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="3" operation="monitor" operation_key="rsc-passes_monitor_0" on_node="cluster01" on_node_uuid="1"/>
 | |
| +      </trigger>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="8" operation="monitor" operation_key="rsc-passes_monitor_0" on_node="cluster02" on_node_uuid="2"/>
 | |
| +      </trigger>
 | |
| +    </inputs>
 | |
| +  </synapse>
 | |
| +  <synapse id="9">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="8" operation="monitor" operation_key="rsc-passes_monitor_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="rsc-passes" class="ocf" provider="heartbeat" type="IPaddr2"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000" cidr_netmask="32"  ip="172.17.1.1"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="10">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="3" operation="monitor" operation_key="rsc-passes_monitor_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="rsc-passes" class="ocf" provider="heartbeat" type="IPaddr2"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000" cidr_netmask="32"  ip="172.17.1.1"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="11">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="17" operation="monitor" operation_key="dummy-rsc_monitor_10000" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="dummy-rsc" class="ocf" provider="pacemaker" type="Dummy"/>
 | |
| +        <attributes CRM_meta_interval="10000" CRM_meta_name="monitor" CRM_meta_on_fail="stop" CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_timeout="20000"  op_sleep="10"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="16" operation="start" operation_key="dummy-rsc_start_0" on_node="cluster02" on_node_uuid="2"/>
 | |
| +      </trigger>
 | |
| +    </inputs>
 | |
| +  </synapse>
 | |
| +  <synapse id="12">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="16" operation="start" operation_key="dummy-rsc_start_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="dummy-rsc" class="ocf" provider="pacemaker" type="Dummy"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_timeout="20000"  op_sleep="10"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="4" operation="monitor" operation_key="dummy-rsc_monitor_0" on_node="cluster01" on_node_uuid="1"/>
 | |
| +      </trigger>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="9" operation="monitor" operation_key="dummy-rsc_monitor_0" on_node="cluster02" on_node_uuid="2"/>
 | |
| +      </trigger>
 | |
| +    </inputs>
 | |
| +  </synapse>
 | |
| +  <synapse id="13">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="9" operation="monitor" operation_key="dummy-rsc_monitor_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="dummy-rsc" class="ocf" provider="pacemaker" type="Dummy"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000"  op_sleep="10"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="14">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="4" operation="monitor" operation_key="dummy-rsc_monitor_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="dummy-rsc" class="ocf" provider="pacemaker" type="Dummy"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000"  op_sleep="10"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="15">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="18" operation="start" operation_key="ping-rsc-ping_start_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="ping-rsc-ping" class="ocf" provider="pacemaker" type="ping"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_timeout="20000"  host_list="4.2.2.2"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="5" operation="monitor" operation_key="ping-rsc-ping_monitor_0" on_node="cluster01" on_node_uuid="1"/>
 | |
| +      </trigger>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="10" operation="monitor" operation_key="ping-rsc-ping_monitor_0" on_node="cluster02" on_node_uuid="2"/>
 | |
| +      </trigger>
 | |
| +    </inputs>
 | |
| +  </synapse>
 | |
| +  <synapse id="16">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="10" operation="monitor" operation_key="ping-rsc-ping_monitor_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="ping-rsc-ping" class="ocf" provider="pacemaker" type="ping"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000"  host_list="4.2.2.2"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="17">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="5" operation="monitor" operation_key="ping-rsc-ping_monitor_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="ping-rsc-ping" class="ocf" provider="pacemaker" type="ping"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000"  host_list="4.2.2.2"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +</transition_graph>
 | |
| diff --git a/cts/scheduler/op-defaults-2.scores b/cts/scheduler/op-defaults-2.scores
 | |
| new file mode 100644
 | |
| index 0000000..180c8b4
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/op-defaults-2.scores
 | |
| @@ -0,0 +1,11 @@
 | |
| +Allocation scores:
 | |
| +pcmk__native_allocate: dummy-rsc allocation score on cluster01: 0
 | |
| +pcmk__native_allocate: dummy-rsc allocation score on cluster02: 0
 | |
| +pcmk__native_allocate: fencing allocation score on cluster01: 0
 | |
| +pcmk__native_allocate: fencing allocation score on cluster02: 0
 | |
| +pcmk__native_allocate: ip-rsc allocation score on cluster01: 0
 | |
| +pcmk__native_allocate: ip-rsc allocation score on cluster02: 0
 | |
| +pcmk__native_allocate: ping-rsc-ping allocation score on cluster01: 0
 | |
| +pcmk__native_allocate: ping-rsc-ping allocation score on cluster02: 0
 | |
| +pcmk__native_allocate: rsc-passes allocation score on cluster01: 0
 | |
| +pcmk__native_allocate: rsc-passes allocation score on cluster02: 0
 | |
| diff --git a/cts/scheduler/op-defaults-2.summary b/cts/scheduler/op-defaults-2.summary
 | |
| new file mode 100644
 | |
| index 0000000..16a68be
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/op-defaults-2.summary
 | |
| @@ -0,0 +1,46 @@
 | |
| +
 | |
| +Current cluster status:
 | |
| +Online: [ cluster01 cluster02 ]
 | |
| +
 | |
| + fencing	(stonith:fence_xvm):	 Stopped
 | |
| + ip-rsc	(ocf::heartbeat:IPaddr2):	 Stopped
 | |
| + rsc-passes	(ocf::heartbeat:IPaddr2):	 Stopped
 | |
| + dummy-rsc	(ocf::pacemaker:Dummy):	 Stopped
 | |
| + ping-rsc-ping	(ocf::pacemaker:ping):	 Stopped
 | |
| +
 | |
| +Transition Summary:
 | |
| + * Start      fencing           ( cluster01 )  
 | |
| + * Start      ip-rsc            ( cluster02 )  
 | |
| + * Start      rsc-passes        ( cluster01 )  
 | |
| + * Start      dummy-rsc         ( cluster02 )  
 | |
| + * Start      ping-rsc-ping     ( cluster01 )  
 | |
| +
 | |
| +Executing cluster transition:
 | |
| + * Resource action: fencing         monitor on cluster02
 | |
| + * Resource action: fencing         monitor on cluster01
 | |
| + * Resource action: ip-rsc          monitor on cluster02
 | |
| + * Resource action: ip-rsc          monitor on cluster01
 | |
| + * Resource action: rsc-passes      monitor on cluster02
 | |
| + * Resource action: rsc-passes      monitor on cluster01
 | |
| + * Resource action: dummy-rsc       monitor on cluster02
 | |
| + * Resource action: dummy-rsc       monitor on cluster01
 | |
| + * Resource action: ping-rsc-ping   monitor on cluster02
 | |
| + * Resource action: ping-rsc-ping   monitor on cluster01
 | |
| + * Resource action: fencing         start on cluster01
 | |
| + * Resource action: ip-rsc          start on cluster02
 | |
| + * Resource action: rsc-passes      start on cluster01
 | |
| + * Resource action: dummy-rsc       start on cluster02
 | |
| + * Resource action: ping-rsc-ping   start on cluster01
 | |
| + * Resource action: ip-rsc          monitor=20000 on cluster02
 | |
| + * Resource action: rsc-passes      monitor=10000 on cluster01
 | |
| + * Resource action: dummy-rsc       monitor=10000 on cluster02
 | |
| +
 | |
| +Revised cluster status:
 | |
| +Online: [ cluster01 cluster02 ]
 | |
| +
 | |
| + fencing	(stonith:fence_xvm):	 Started cluster01
 | |
| + ip-rsc	(ocf::heartbeat:IPaddr2):	 Started cluster02
 | |
| + rsc-passes	(ocf::heartbeat:IPaddr2):	 Started cluster01
 | |
| + dummy-rsc	(ocf::pacemaker:Dummy):	 Started cluster02
 | |
| + ping-rsc-ping	(ocf::pacemaker:ping):	 Started cluster01
 | |
| +
 | |
| diff --git a/cts/scheduler/op-defaults-2.xml b/cts/scheduler/op-defaults-2.xml
 | |
| new file mode 100644
 | |
| index 0000000..9f3c288
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/op-defaults-2.xml
 | |
| @@ -0,0 +1,73 @@
 | |
| +<cib crm_feature_set="3.3.0" validate-with="pacemaker-3.4" epoch="130" num_updates="31" admin_epoch="1" cib-last-written="Fri Apr 24 16:08:36 2020" update-origin="cluster01" update-client="crmd" update-user="hacluster" have-quorum="1" dc-uuid="1">
 | |
| +  <configuration>
 | |
| +    <crm_config>
 | |
| +      <cluster_property_set id="cib-bootstrap-options">
 | |
| +        <nvpair id="cib-bootstrap-options-have-watchdog" name="have-watchdog" value="false"/>
 | |
| +        <nvpair id="cib-bootstrap-options-dc-version" name="dc-version" value="2.0.3-1.c40fb040a.git.el7-c40fb040a"/>
 | |
| +        <nvpair id="cib-bootstrap-options-cluster-infrastructure" name="cluster-infrastructure" value="corosync"/>
 | |
| +        <nvpair id="cib-bootstrap-options-cluster-name" name="cluster-name" value="test-cluster"/>
 | |
| +        <nvpair id="cib-bootstrap-options-stonith-enabled" name="stonith-enabled" value="true"/>
 | |
| +        <nvpair id="cib-bootstrap-options-maintenance-mode" name="maintenance-mode" value="false"/>
 | |
| +      </cluster_property_set>
 | |
| +    </crm_config>
 | |
| +    <nodes>
 | |
| +      <node id="1" uname="cluster01"/>
 | |
| +      <node id="2" uname="cluster02"/>
 | |
| +    </nodes>
 | |
| +    <resources>
 | |
| +      <primitive class="stonith" id="fencing" type="fence_xvm">
 | |
| +        <instance_attributes id="fencing-instance_attributes">
 | |
| +          <nvpair id="fencing-instance_attributes-ip_family" name="ip_family" value="ipv4"/>
 | |
| +        </instance_attributes>
 | |
| +        <operations/>
 | |
| +      </primitive>
 | |
| +      <primitive class="ocf" id="ip-rsc" provider="heartbeat" type="IPaddr2">
 | |
| +        <instance_attributes id="ip-rsc-instance_attributes">
 | |
| +          <nvpair id="ip-rsc-instance_attributes-cidr_netmask" name="cidr_netmask" value="32"/>
 | |
| +          <nvpair id="ip-rsc-instance_attributes-ip" name="ip" value="172.17.1.1"/>
 | |
| +        </instance_attributes>
 | |
| +        <operations>
 | |
| +          <op id="ip-rsc-monitor-interval-20s" interval="20s" name="monitor"/>
 | |
| +        </operations>
 | |
| +      </primitive>
 | |
| +      <primitive class="ocf" id="rsc-passes" provider="heartbeat" type="IPaddr2">
 | |
| +        <instance_attributes id="rsc-passes-instance_attributes">
 | |
| +          <nvpair id="rsc-passes-instance_attributes-cidr_netmask" name="cidr_netmask" value="32"/>
 | |
| +          <nvpair id="rsc-passes-instance_attributes-ip" name="ip" value="172.17.1.1"/>
 | |
| +        </instance_attributes>
 | |
| +        <operations>
 | |
| +          <op id="rsc-passes-monitor-interval-10s" interval="10s" name="monitor"/>
 | |
| +        </operations>
 | |
| +      </primitive>
 | |
| +      <primitive class="ocf" id="dummy-rsc" provider="pacemaker" type="Dummy">
 | |
| +        <instance_attributes id="dummy-rsc-instance_attributes">
 | |
| +          <nvpair id="dummy-rsc-instance_attributes-op_sleep" name="op_sleep" value="10"/>
 | |
| +        </instance_attributes>
 | |
| +        <operations>
 | |
| +          <op id="dummy-rsc-monitor-interval-10s" interval="10s" name="monitor" on-fail="stop"/>
 | |
| +        </operations>
 | |
| +      </primitive>
 | |
| +      <primitive class="ocf" id="ping-rsc-ping" provider="pacemaker" type="ping">
 | |
| +        <instance_attributes id="ping-rsc-instance_attributes">
 | |
| +          <nvpair id="ping-rsc-host_list" name="host_list" value="4.2.2.2"/>
 | |
| +        </instance_attributes>
 | |
| +        <operations/>
 | |
| +      </primitive>
 | |
| +    </resources>
 | |
| +    <constraints/>
 | |
| +    <tags/>
 | |
| +    <op_defaults>
 | |
| +      <meta_attributes id="op-monitor-and">
 | |
| +        <rule id="op-monitor-and-rule" score="INFINITY">
 | |
| +          <rsc_expression id="op-monitor-and-rsc-expr" class="ocf" provider="heartbeat" type="IPaddr2"/>
 | |
| +          <op_expression id="op-monitor-and-op-expr" name="monitor" interval="10s"/>
 | |
| +        </rule>
 | |
| +        <nvpair id="op-monitor-and-timeout" name="timeout" value="8s"/>
 | |
| +      </meta_attributes>
 | |
| +    </op_defaults>
 | |
| +  </configuration>
 | |
| +  <status>
 | |
| +    <node_state id="1" uname="cluster01" in_ccm="true" crmd="online" crm-debug-origin="do_state_transition" join="member" expected="member"/>
 | |
| +    <node_state id="2" uname="cluster02" in_ccm="true" crmd="online" crm-debug-origin="do_update_resource" join="member" expected="member"/>
 | |
| +  </status>
 | |
| +</cib>
 | |
| -- 
 | |
| 1.8.3.1
 | |
| 
 | |
| 
 | |
| From 017b783c2037d641c40a39dd7ec3a9eba0aaa6df Mon Sep 17 00:00:00 2001
 | |
| From: Chris Lumens <clumens@redhat.com>
 | |
| Date: Wed, 13 May 2020 15:18:28 -0400
 | |
| Subject: [PATCH 15/17] Doc: Pacemaker Explained: Add documentation for
 | |
|  rsc_expr and op_expr.
 | |
| 
 | |
| ---
 | |
|  doc/Pacemaker_Explained/en-US/Ch-Rules.txt | 174 +++++++++++++++++++++++++++++
 | |
|  1 file changed, 174 insertions(+)
 | |
| 
 | |
| diff --git a/doc/Pacemaker_Explained/en-US/Ch-Rules.txt b/doc/Pacemaker_Explained/en-US/Ch-Rules.txt
 | |
| index 9d617f6..5df5f82 100644
 | |
| --- a/doc/Pacemaker_Explained/en-US/Ch-Rules.txt
 | |
| +++ b/doc/Pacemaker_Explained/en-US/Ch-Rules.txt
 | |
| @@ -522,6 +522,124 @@ You may wish to write +end="2005-03-31T23:59:59"+ to avoid confusion.
 | |
|  -------
 | |
|  =====
 | |
|  
 | |
| +== Resource Expressions ==
 | |
| +
 | |
| +An +rsc_expression+ is a rule condition based on a resource agent's properties.
 | |
| +This rule is only valid within an +rsc_defaults+ or +op_defaults+ context.  None
 | |
| +of the matching attributes of +class+, +provider+, and +type+ are required.  If
 | |
| +one is omitted, all values of that attribute will match.  For instance, omitting
 | |
| ++type+ means every type will match.
 | |
| +
 | |
| +.Attributes of an rsc_expression Element
 | |
| +[width="95%",cols="2m,<5",options="header",align="center"]
 | |
| +|=========================================================
 | |
| +
 | |
| +|Field
 | |
| +|Description
 | |
| +
 | |
| +|id
 | |
| +|A unique name for the expression (required)
 | |
| + indexterm:[XML attribute,id attribute,rsc_expression element]
 | |
| + indexterm:[XML element,rsc_expression element,id attribute]
 | |
| +
 | |
| +|class
 | |
| +|The standard name to be matched against resource agents
 | |
| + indexterm:[XML attribute,class attribute,rsc_expression element]
 | |
| + indexterm:[XML element,rsc_expression element,class attribute]
 | |
| +
 | |
| +|provider
 | |
| +|If given, the vendor to be matched against resource agents.  This
 | |
| + only makes sense for agents using the OCF spec.
 | |
| + indexterm:[XML attribute,provider attribute,rsc_expression element]
 | |
| + indexterm:[XML element,rsc_expression element,provider attribute]
 | |
| +
 | |
| +|type
 | |
| +|The name of the resource agent to be matched
 | |
| + indexterm:[XML attribute,type attribute,rsc_expression element]
 | |
| + indexterm:[XML element,rsc_expression element,type attribute]
 | |
| +
 | |
| +|=========================================================
 | |
| +
 | |
| +=== Example Resource-Based Expressions ===
 | |
| +
 | |
| +A small sample of how resource-based expressions can be used:
 | |
| +
 | |
| +.True for all ocf:heartbeat:IPaddr2 resources
 | |
| +====
 | |
| +[source,XML]
 | |
| +----
 | |
| +<rule id="rule1" score="INFINITY">
 | |
| +    <rsc_expression id="rule_expr1" class="ocf" provider="heartbeat" type="IPaddr2"/>
 | |
| +</rule>
 | |
| +----
 | |
| +====
 | |
| +
 | |
| +.Provider doesn't apply to non-OCF resources
 | |
| +====
 | |
| +[source,XML]
 | |
| +----
 | |
| +<rule id="rule2" score="INFINITY">
 | |
| +    <rsc_expression id="rule_expr2" class="stonith" type="fence_xvm"/>
 | |
| +</rule>
 | |
| +----
 | |
| +====
 | |
| +
 | |
| +== Operation Expressions ==
 | |
| +
 | |
| +An +op_expression+ is a rule condition based on an action of some resource
 | |
| +agent.  This rule is only valid within an +op_defaults+ context.
 | |
| +
 | |
| +.Attributes of an op_expression Element
 | |
| +[width="95%",cols="2m,<5",options="header",align="center"]
 | |
| +|=========================================================
 | |
| +
 | |
| +|Field
 | |
| +|Description
 | |
| +
 | |
| +|id
 | |
| +|A unique name for the expression (required)
 | |
| + indexterm:[XML attribute,id attribute,op_expression element]
 | |
| + indexterm:[XML element,op_expression element,id attribute]
 | |
| +
 | |
| +|name
 | |
| +|The action name to match against.  This can be any action supported by
 | |
| + the resource agent; common values include +monitor+, +start+, and +stop+
 | |
| + (required).
 | |
| + indexterm:[XML attribute,name attribute,op_expression element]
 | |
| + indexterm:[XML element,op_expression element,name attribute]
 | |
| +
 | |
| +|interval
 | |
| +|The interval of the action to match against.  If not given, only
 | |
| + the name attribute will be used to match.
 | |
| + indexterm:[XML attribute,interval attribute,op_expression element]
 | |
| + indexterm:[XML element,op_expression element,interval attribute]
 | |
| +
 | |
| +|=========================================================
 | |
| +
 | |
| +=== Example Operation-Based Expressions ===
 | |
| +
 | |
| +A small sample of how operation-based expressions can be used:
 | |
| +
 | |
| +.True for all monitor actions
 | |
| +====
 | |
| +[source,XML]
 | |
| +----
 | |
| +<rule id="rule1" score="INFINITY">
 | |
| +    <op_expression id="rule_expr1" name="monitor"/>
 | |
| +</rule>
 | |
| +----
 | |
| +====
 | |
| +
 | |
| +.True for all monitor actions with a 10 second interval
 | |
| +====
 | |
| +[source,XML]
 | |
| +----
 | |
| +<rule id="rule2" score="INFINITY">
 | |
| +    <op_expression id="rule_expr2" name="monitor" interval="10s"/>
 | |
| +</rule>
 | |
| +----
 | |
| +====
 | |
| +
 | |
|  == Using Rules to Determine Resource Location ==
 | |
|  indexterm:[Rule,Determine Resource Location]
 | |
|  indexterm:[Resource,Location,Determine by Rules]
 | |
| @@ -710,6 +828,62 @@ Rules may be used similarly in +instance_attributes+ or +utilization+ blocks.
 | |
|  Any single block may directly contain only a single rule, but that rule may
 | |
|  itself contain any number of rules.
 | |
|  
 | |
| ++rsc_expression+ and +op_expression+ blocks may additionally be used to set defaults
 | |
| +on either a single resource or across an entire class of resources with a single
 | |
| +rule.  +rsc_expression+ may be used to select resource agents within both +rsc_defaults+
 | |
| +and +op_defaults+, while +op_expression+ may only be used within +op_defaults+.  If
 | |
| +multiple rules succeed for a given resource agent, the last one specified will be
 | |
| +the one that takes effect.  As with any other rule, boolean operations may be used
 | |
| +to make more complicated expressions.
 | |
| +
 | |
| +.Set all IPaddr2 resources to stopped
 | |
| +=====
 | |
| +[source,XML]
 | |
| +-------
 | |
| +<rsc_defaults>
 | |
| +    <meta_attributes id="op-target-role">
 | |
| +        <rule id="op-target-role-rule" score="INFINITY">
 | |
| +            <rsc_expression id="op-target-role-expr" class="ocf" provider="heartbeat"
 | |
| +              type="IPaddr2"/>
 | |
| +        </rule>
 | |
| +        <nvpair id="op-target-role-nvpair" name="target-role" value="Stopped"/>
 | |
| +    </meta_attributes>
 | |
| +</rsc_defaults>
 | |
| +-------
 | |
| +=====
 | |
| +
 | |
| +.Set all monitor action timeouts to 7 seconds
 | |
| +=====
 | |
| +[source,XML]
 | |
| +-------
 | |
| +<op_defaults>
 | |
| +    <meta_attributes id="op-monitor-defaults">
 | |
| +        <rule id="op-monitor-default-rule" score="INFINITY">
 | |
| +            <op_expression id="op-monitor-default-expr" name="monitor"/>
 | |
| +        </rule>
 | |
| +        <nvpair id="op-monitor-timeout" name="timeout" value="7s"/>
 | |
| +    </meta_attributes>
 | |
| +</op_defaults>
 | |
| +-------
 | |
| +=====
 | |
| +
 | |
| +.Set the monitor action timeout on all IPaddr2 resources with a given monitor interval to 8 seconds
 | |
| +=====
 | |
| +[source,XML]
 | |
| +-------
 | |
| +<op_defaults>
 | |
| +    <meta_attributes id="op-monitor-and">
 | |
| +        <rule id="op-monitor-and-rule" score="INFINITY">
 | |
| +            <rsc_expression id="op-monitor-and-rsc-expr" class="ocf" provider="heartbeat"
 | |
| +              type="IPaddr2"/>
 | |
| +            <op_expression id="op-monitor-and-op-expr" name="monitor" interval="10s"/>
 | |
| +        </rule>
 | |
| +        <nvpair id="op-monitor-and-timeout" name="timeout" value="8s"/>
 | |
| +    </meta_attributes>
 | |
| +</op_defaults>
 | |
| +-------
 | |
| +=====
 | |
| +
 | |
|  === Using Rules to Control Cluster Options ===
 | |
|  indexterm:[Rule,Controlling Cluster Options]
 | |
|  indexterm:[Cluster,Setting Options with Rules]
 | |
| -- 
 | |
| 1.8.3.1
 | |
| 
 | |
| 
 | |
| From b8dd16c5e454445f73416ae8b74649545ee1b472 Mon Sep 17 00:00:00 2001
 | |
| From: Chris Lumens <clumens@redhat.com>
 | |
| Date: Wed, 13 May 2020 16:26:21 -0400
 | |
| Subject: [PATCH 16/17] Test: scheduler: Add a test for multiple rules applying
 | |
|  to the same resource.
 | |
| 
 | |
| ---
 | |
|  cts/cts-scheduler.in                |  1 +
 | |
|  cts/scheduler/op-defaults-3.dot     | 14 +++++++
 | |
|  cts/scheduler/op-defaults-3.exp     | 83 +++++++++++++++++++++++++++++++++++++
 | |
|  cts/scheduler/op-defaults-3.scores  |  5 +++
 | |
|  cts/scheduler/op-defaults-3.summary | 26 ++++++++++++
 | |
|  cts/scheduler/op-defaults-3.xml     | 54 ++++++++++++++++++++++++
 | |
|  6 files changed, 183 insertions(+)
 | |
|  create mode 100644 cts/scheduler/op-defaults-3.dot
 | |
|  create mode 100644 cts/scheduler/op-defaults-3.exp
 | |
|  create mode 100644 cts/scheduler/op-defaults-3.scores
 | |
|  create mode 100644 cts/scheduler/op-defaults-3.summary
 | |
|  create mode 100644 cts/scheduler/op-defaults-3.xml
 | |
| 
 | |
| diff --git a/cts/cts-scheduler.in b/cts/cts-scheduler.in
 | |
| index 669b344..2c2d14f 100644
 | |
| --- a/cts/cts-scheduler.in
 | |
| +++ b/cts/cts-scheduler.in
 | |
| @@ -965,6 +965,7 @@ TESTS = [
 | |
|      [
 | |
|          [ "op-defaults", "Test op_defaults conditional expressions" ],
 | |
|          [ "op-defaults-2", "Test op_defaults AND'ed conditional expressions" ],
 | |
| +        [ "op-defaults-3", "Test op_defaults precedence" ],
 | |
|          [ "rsc-defaults", "Test rsc_defaults conditional expressions" ],
 | |
|      ],
 | |
|      
 | |
| diff --git a/cts/scheduler/op-defaults-3.dot b/cts/scheduler/op-defaults-3.dot
 | |
| new file mode 100644
 | |
| index 0000000..382f630
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/op-defaults-3.dot
 | |
| @@ -0,0 +1,14 @@
 | |
| + digraph "g" {
 | |
| +"dummy-rsc_monitor_0 cluster01" -> "dummy-rsc_start_0 cluster02" [ style = bold]
 | |
| +"dummy-rsc_monitor_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"dummy-rsc_monitor_0 cluster02" -> "dummy-rsc_start_0 cluster02" [ style = bold]
 | |
| +"dummy-rsc_monitor_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"dummy-rsc_monitor_10000 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"dummy-rsc_start_0 cluster02" -> "dummy-rsc_monitor_10000 cluster02" [ style = bold]
 | |
| +"dummy-rsc_start_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"fencing_monitor_0 cluster01" -> "fencing_start_0 cluster01" [ style = bold]
 | |
| +"fencing_monitor_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"fencing_monitor_0 cluster02" -> "fencing_start_0 cluster01" [ style = bold]
 | |
| +"fencing_monitor_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"fencing_start_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +}
 | |
| diff --git a/cts/scheduler/op-defaults-3.exp b/cts/scheduler/op-defaults-3.exp
 | |
| new file mode 100644
 | |
| index 0000000..6d567dc
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/op-defaults-3.exp
 | |
| @@ -0,0 +1,83 @@
 | |
| +<transition_graph cluster-delay="60s" stonith-timeout="60s" failed-stop-offset="INFINITY" failed-start-offset="INFINITY"  transition_id="0">
 | |
| +  <synapse id="0">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="5" operation="start" operation_key="fencing_start_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="fencing" class="stonith" type="fence_xvm"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_timeout="20000"  ip_family="ipv4"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="1" operation="monitor" operation_key="fencing_monitor_0" on_node="cluster01" on_node_uuid="1"/>
 | |
| +      </trigger>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="3" operation="monitor" operation_key="fencing_monitor_0" on_node="cluster02" on_node_uuid="2"/>
 | |
| +      </trigger>
 | |
| +    </inputs>
 | |
| +  </synapse>
 | |
| +  <synapse id="1">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="3" operation="monitor" operation_key="fencing_monitor_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="fencing" class="stonith" type="fence_xvm"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_op_target_rc="7" CRM_meta_timeout="7000"  ip_family="ipv4"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="2">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="1" operation="monitor" operation_key="fencing_monitor_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="fencing" class="stonith" type="fence_xvm"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_op_target_rc="7" CRM_meta_timeout="7000"  ip_family="ipv4"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="3">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="7" operation="monitor" operation_key="dummy-rsc_monitor_10000" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="dummy-rsc" class="ocf" provider="pacemaker" type="Dummy"/>
 | |
| +        <attributes CRM_meta_interval="10000" CRM_meta_name="monitor" CRM_meta_on_fail="stop" CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_timeout="7000"  op_sleep="10"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="6" operation="start" operation_key="dummy-rsc_start_0" on_node="cluster02" on_node_uuid="2"/>
 | |
| +      </trigger>
 | |
| +    </inputs>
 | |
| +  </synapse>
 | |
| +  <synapse id="4">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="6" operation="start" operation_key="dummy-rsc_start_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="dummy-rsc" class="ocf" provider="pacemaker" type="Dummy"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_timeout="20000"  op_sleep="10"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="2" operation="monitor" operation_key="dummy-rsc_monitor_0" on_node="cluster01" on_node_uuid="1"/>
 | |
| +      </trigger>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="4" operation="monitor" operation_key="dummy-rsc_monitor_0" on_node="cluster02" on_node_uuid="2"/>
 | |
| +      </trigger>
 | |
| +    </inputs>
 | |
| +  </synapse>
 | |
| +  <synapse id="5">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="4" operation="monitor" operation_key="dummy-rsc_monitor_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="dummy-rsc" class="ocf" provider="pacemaker" type="Dummy"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_op_target_rc="7" CRM_meta_timeout="7000"  op_sleep="10"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="6">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="2" operation="monitor" operation_key="dummy-rsc_monitor_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="dummy-rsc" class="ocf" provider="pacemaker" type="Dummy"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_op_target_rc="7" CRM_meta_timeout="7000"  op_sleep="10"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +</transition_graph>
 | |
| diff --git a/cts/scheduler/op-defaults-3.scores b/cts/scheduler/op-defaults-3.scores
 | |
| new file mode 100644
 | |
| index 0000000..0a5190a
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/op-defaults-3.scores
 | |
| @@ -0,0 +1,5 @@
 | |
| +Allocation scores:
 | |
| +pcmk__native_allocate: dummy-rsc allocation score on cluster01: 0
 | |
| +pcmk__native_allocate: dummy-rsc allocation score on cluster02: 0
 | |
| +pcmk__native_allocate: fencing allocation score on cluster01: 0
 | |
| +pcmk__native_allocate: fencing allocation score on cluster02: 0
 | |
| diff --git a/cts/scheduler/op-defaults-3.summary b/cts/scheduler/op-defaults-3.summary
 | |
| new file mode 100644
 | |
| index 0000000..a83eb15
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/op-defaults-3.summary
 | |
| @@ -0,0 +1,26 @@
 | |
| +
 | |
| +Current cluster status:
 | |
| +Online: [ cluster01 cluster02 ]
 | |
| +
 | |
| + fencing	(stonith:fence_xvm):	 Stopped
 | |
| + dummy-rsc	(ocf::pacemaker:Dummy):	 Stopped
 | |
| +
 | |
| +Transition Summary:
 | |
| + * Start      fencing     ( cluster01 )  
 | |
| + * Start      dummy-rsc   ( cluster02 )  
 | |
| +
 | |
| +Executing cluster transition:
 | |
| + * Resource action: fencing         monitor on cluster02
 | |
| + * Resource action: fencing         monitor on cluster01
 | |
| + * Resource action: dummy-rsc       monitor on cluster02
 | |
| + * Resource action: dummy-rsc       monitor on cluster01
 | |
| + * Resource action: fencing         start on cluster01
 | |
| + * Resource action: dummy-rsc       start on cluster02
 | |
| + * Resource action: dummy-rsc       monitor=10000 on cluster02
 | |
| +
 | |
| +Revised cluster status:
 | |
| +Online: [ cluster01 cluster02 ]
 | |
| +
 | |
| + fencing	(stonith:fence_xvm):	 Started cluster01
 | |
| + dummy-rsc	(ocf::pacemaker:Dummy):	 Started cluster02
 | |
| +
 | |
| diff --git a/cts/scheduler/op-defaults-3.xml b/cts/scheduler/op-defaults-3.xml
 | |
| new file mode 100644
 | |
| index 0000000..4a8912e
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/op-defaults-3.xml
 | |
| @@ -0,0 +1,54 @@
 | |
| +<cib crm_feature_set="3.3.0" validate-with="pacemaker-3.4" epoch="130" num_updates="31" admin_epoch="1" cib-last-written="Fri Apr 24 16:08:36 2020" update-origin="cluster01" update-client="crmd" update-user="hacluster" have-quorum="1" dc-uuid="1">
 | |
| +  <configuration>
 | |
| +    <crm_config>
 | |
| +      <cluster_property_set id="cib-bootstrap-options">
 | |
| +        <nvpair id="cib-bootstrap-options-have-watchdog" name="have-watchdog" value="false"/>
 | |
| +        <nvpair id="cib-bootstrap-options-dc-version" name="dc-version" value="2.0.3-1.c40fb040a.git.el7-c40fb040a"/>
 | |
| +        <nvpair id="cib-bootstrap-options-cluster-infrastructure" name="cluster-infrastructure" value="corosync"/>
 | |
| +        <nvpair id="cib-bootstrap-options-cluster-name" name="cluster-name" value="test-cluster"/>
 | |
| +        <nvpair id="cib-bootstrap-options-stonith-enabled" name="stonith-enabled" value="true"/>
 | |
| +        <nvpair id="cib-bootstrap-options-maintenance-mode" name="maintenance-mode" value="false"/>
 | |
| +      </cluster_property_set>
 | |
| +    </crm_config>
 | |
| +    <nodes>
 | |
| +      <node id="1" uname="cluster01"/>
 | |
| +      <node id="2" uname="cluster02"/>
 | |
| +    </nodes>
 | |
| +    <resources>
 | |
| +      <primitive class="stonith" id="fencing" type="fence_xvm">
 | |
| +        <instance_attributes id="fencing-instance_attributes">
 | |
| +          <nvpair id="fencing-instance_attributes-ip_family" name="ip_family" value="ipv4"/>
 | |
| +        </instance_attributes>
 | |
| +        <operations/>
 | |
| +      </primitive>
 | |
| +      <primitive class="ocf" id="dummy-rsc" provider="pacemaker" type="Dummy">
 | |
| +        <instance_attributes id="dummy-rsc-instance_attributes">
 | |
| +          <nvpair id="dummy-rsc-instance_attributes-op_sleep" name="op_sleep" value="10"/>
 | |
| +        </instance_attributes>
 | |
| +        <operations>
 | |
| +          <op id="dummy-rsc-monitor-interval-10s" interval="10s" name="monitor" on-fail="stop"/>
 | |
| +        </operations>
 | |
| +      </primitive>
 | |
| +    </resources>
 | |
| +    <constraints/>
 | |
| +    <tags/>
 | |
| +    <op_defaults>
 | |
| +      <meta_attributes id="op-10s-monitor-defaults">
 | |
| +        <rule id="op-10s-monitor-default-rule" score="INFINITY">
 | |
| +          <op_expression id="op-10s-monitor-default-expr" name="monitor" interval="10s"/>
 | |
| +        </rule>
 | |
| +        <nvpair id="op-10s-monitor-timeout" name="timeout" value="8s"/>
 | |
| +      </meta_attributes>
 | |
| +      <meta_attributes id="op-monitor-defaults">
 | |
| +        <rule id="op-monitor-default-rule" score="INFINITY">
 | |
| +          <op_expression id="op-monitor-default-expr" name="monitor"/>
 | |
| +        </rule>
 | |
| +        <nvpair id="op-monitor-timeout" name="timeout" value="7s"/>
 | |
| +      </meta_attributes>
 | |
| +    </op_defaults>
 | |
| +  </configuration>
 | |
| +  <status>
 | |
| +    <node_state id="1" uname="cluster01" in_ccm="true" crmd="online" crm-debug-origin="do_state_transition" join="member" expected="member"/>
 | |
| +    <node_state id="2" uname="cluster02" in_ccm="true" crmd="online" crm-debug-origin="do_update_resource" join="member" expected="member"/>
 | |
| +  </status>
 | |
| +</cib>
 | |
| -- 
 | |
| 1.8.3.1
 | |
| 
 | |
| 
 | |
| From b9ccde16609e7d005ac0578a603da97a1808704a Mon Sep 17 00:00:00 2001
 | |
| From: Chris Lumens <clumens@redhat.com>
 | |
| Date: Fri, 15 May 2020 13:48:47 -0400
 | |
| Subject: [PATCH 17/17] Test: scheduler: Add a test for rsc_defaults not
 | |
|  specifying type.
 | |
| 
 | |
| ---
 | |
|  cts/cts-scheduler.in                 |  1 +
 | |
|  cts/scheduler/rsc-defaults-2.dot     | 11 ++++++
 | |
|  cts/scheduler/rsc-defaults-2.exp     | 72 ++++++++++++++++++++++++++++++++++++
 | |
|  cts/scheduler/rsc-defaults-2.scores  |  7 ++++
 | |
|  cts/scheduler/rsc-defaults-2.summary | 27 ++++++++++++++
 | |
|  cts/scheduler/rsc-defaults-2.xml     | 52 ++++++++++++++++++++++++++
 | |
|  6 files changed, 170 insertions(+)
 | |
|  create mode 100644 cts/scheduler/rsc-defaults-2.dot
 | |
|  create mode 100644 cts/scheduler/rsc-defaults-2.exp
 | |
|  create mode 100644 cts/scheduler/rsc-defaults-2.scores
 | |
|  create mode 100644 cts/scheduler/rsc-defaults-2.summary
 | |
|  create mode 100644 cts/scheduler/rsc-defaults-2.xml
 | |
| 
 | |
| diff --git a/cts/cts-scheduler.in b/cts/cts-scheduler.in
 | |
| index 2c2d14f..346ada2 100644
 | |
| --- a/cts/cts-scheduler.in
 | |
| +++ b/cts/cts-scheduler.in
 | |
| @@ -967,6 +967,7 @@ TESTS = [
 | |
|          [ "op-defaults-2", "Test op_defaults AND'ed conditional expressions" ],
 | |
|          [ "op-defaults-3", "Test op_defaults precedence" ],
 | |
|          [ "rsc-defaults", "Test rsc_defaults conditional expressions" ],
 | |
| +        [ "rsc-defaults-2", "Test rsc_defaults conditional expressions without type" ],
 | |
|      ],
 | |
|      
 | |
|      # @TODO: If pacemaker implements versioned attributes, uncomment these tests
 | |
| diff --git a/cts/scheduler/rsc-defaults-2.dot b/cts/scheduler/rsc-defaults-2.dot
 | |
| new file mode 100644
 | |
| index 0000000..b43c5e6
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/rsc-defaults-2.dot
 | |
| @@ -0,0 +1,11 @@
 | |
| + digraph "g" {
 | |
| +"dummy-rsc_monitor_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"dummy-rsc_monitor_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"fencing_monitor_0 cluster01" -> "fencing_start_0 cluster01" [ style = bold]
 | |
| +"fencing_monitor_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"fencing_monitor_0 cluster02" -> "fencing_start_0 cluster01" [ style = bold]
 | |
| +"fencing_monitor_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +"fencing_start_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"ping-rsc-ping_monitor_0 cluster01" [ style=bold color="green" fontcolor="black"]
 | |
| +"ping-rsc-ping_monitor_0 cluster02" [ style=bold color="green" fontcolor="black"]
 | |
| +}
 | |
| diff --git a/cts/scheduler/rsc-defaults-2.exp b/cts/scheduler/rsc-defaults-2.exp
 | |
| new file mode 100644
 | |
| index 0000000..e9e1b5f
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/rsc-defaults-2.exp
 | |
| @@ -0,0 +1,72 @@
 | |
| +<transition_graph cluster-delay="60s" stonith-timeout="60s" failed-stop-offset="INFINITY" failed-start-offset="INFINITY"  transition_id="0">
 | |
| +  <synapse id="0">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="7" operation="start" operation_key="fencing_start_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="fencing" class="stonith" type="fence_xvm"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_timeout="20000"  ip_family="ipv4"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="1" operation="monitor" operation_key="fencing_monitor_0" on_node="cluster01" on_node_uuid="1"/>
 | |
| +      </trigger>
 | |
| +      <trigger>
 | |
| +        <rsc_op id="4" operation="monitor" operation_key="fencing_monitor_0" on_node="cluster02" on_node_uuid="2"/>
 | |
| +      </trigger>
 | |
| +    </inputs>
 | |
| +  </synapse>
 | |
| +  <synapse id="1">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="4" operation="monitor" operation_key="fencing_monitor_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="fencing" class="stonith" type="fence_xvm"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000"  ip_family="ipv4"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="2">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="1" operation="monitor" operation_key="fencing_monitor_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="fencing" class="stonith" type="fence_xvm"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000"  ip_family="ipv4"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="3">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="5" operation="monitor" operation_key="dummy-rsc_monitor_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="dummy-rsc" class="ocf" provider="pacemaker" type="Dummy"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000"  op_sleep="10"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="4">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="2" operation="monitor" operation_key="dummy-rsc_monitor_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="dummy-rsc" class="ocf" provider="pacemaker" type="Dummy"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000"  op_sleep="10"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="5">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="6" operation="monitor" operation_key="ping-rsc-ping_monitor_0" on_node="cluster02" on_node_uuid="2">
 | |
| +        <primitive id="ping-rsc-ping" class="ocf" provider="pacemaker" type="ping"/>
 | |
| +        <attributes CRM_meta_on_node="cluster02" CRM_meta_on_node_uuid="2" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000"  host_list="4.2.2.2"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +  <synapse id="6">
 | |
| +    <action_set>
 | |
| +      <rsc_op id="3" operation="monitor" operation_key="ping-rsc-ping_monitor_0" on_node="cluster01" on_node_uuid="1">
 | |
| +        <primitive id="ping-rsc-ping" class="ocf" provider="pacemaker" type="ping"/>
 | |
| +        <attributes CRM_meta_on_node="cluster01" CRM_meta_on_node_uuid="1" CRM_meta_op_target_rc="7" CRM_meta_timeout="20000"  host_list="4.2.2.2"/>
 | |
| +      </rsc_op>
 | |
| +    </action_set>
 | |
| +    <inputs/>
 | |
| +  </synapse>
 | |
| +</transition_graph>
 | |
| diff --git a/cts/scheduler/rsc-defaults-2.scores b/cts/scheduler/rsc-defaults-2.scores
 | |
| new file mode 100644
 | |
| index 0000000..4b70f54
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/rsc-defaults-2.scores
 | |
| @@ -0,0 +1,7 @@
 | |
| +Allocation scores:
 | |
| +pcmk__native_allocate: dummy-rsc allocation score on cluster01: 0
 | |
| +pcmk__native_allocate: dummy-rsc allocation score on cluster02: 0
 | |
| +pcmk__native_allocate: fencing allocation score on cluster01: 0
 | |
| +pcmk__native_allocate: fencing allocation score on cluster02: 0
 | |
| +pcmk__native_allocate: ping-rsc-ping allocation score on cluster01: 0
 | |
| +pcmk__native_allocate: ping-rsc-ping allocation score on cluster02: 0
 | |
| diff --git a/cts/scheduler/rsc-defaults-2.summary b/cts/scheduler/rsc-defaults-2.summary
 | |
| new file mode 100644
 | |
| index 0000000..46a2a2d
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/rsc-defaults-2.summary
 | |
| @@ -0,0 +1,27 @@
 | |
| +
 | |
| +Current cluster status:
 | |
| +Online: [ cluster01 cluster02 ]
 | |
| +
 | |
| + fencing	(stonith:fence_xvm):	 Stopped
 | |
| + dummy-rsc	(ocf::pacemaker:Dummy):	 Stopped (unmanaged)
 | |
| + ping-rsc-ping	(ocf::pacemaker:ping):	 Stopped (unmanaged)
 | |
| +
 | |
| +Transition Summary:
 | |
| + * Start      fencing     ( cluster01 )  
 | |
| +
 | |
| +Executing cluster transition:
 | |
| + * Resource action: fencing         monitor on cluster02
 | |
| + * Resource action: fencing         monitor on cluster01
 | |
| + * Resource action: dummy-rsc       monitor on cluster02
 | |
| + * Resource action: dummy-rsc       monitor on cluster01
 | |
| + * Resource action: ping-rsc-ping   monitor on cluster02
 | |
| + * Resource action: ping-rsc-ping   monitor on cluster01
 | |
| + * Resource action: fencing         start on cluster01
 | |
| +
 | |
| +Revised cluster status:
 | |
| +Online: [ cluster01 cluster02 ]
 | |
| +
 | |
| + fencing	(stonith:fence_xvm):	 Started cluster01
 | |
| + dummy-rsc	(ocf::pacemaker:Dummy):	 Stopped (unmanaged)
 | |
| + ping-rsc-ping	(ocf::pacemaker:ping):	 Stopped (unmanaged)
 | |
| +
 | |
| diff --git a/cts/scheduler/rsc-defaults-2.xml b/cts/scheduler/rsc-defaults-2.xml
 | |
| new file mode 100644
 | |
| index 0000000..a160fae
 | |
| --- /dev/null
 | |
| +++ b/cts/scheduler/rsc-defaults-2.xml
 | |
| @@ -0,0 +1,52 @@
 | |
| +<cib crm_feature_set="3.3.0" validate-with="pacemaker-3.4" epoch="130" num_updates="31" admin_epoch="1" cib-last-written="Fri Apr 24 16:08:36 2020" update-origin="cluster01" update-client="crmd" update-user="hacluster" have-quorum="1" dc-uuid="1">
 | |
| +  <configuration>
 | |
| +    <crm_config>
 | |
| +      <cluster_property_set id="cib-bootstrap-options">
 | |
| +        <nvpair id="cib-bootstrap-options-have-watchdog" name="have-watchdog" value="false"/>
 | |
| +        <nvpair id="cib-bootstrap-options-dc-version" name="dc-version" value="2.0.3-1.c40fb040a.git.el7-c40fb040a"/>
 | |
| +        <nvpair id="cib-bootstrap-options-cluster-infrastructure" name="cluster-infrastructure" value="corosync"/>
 | |
| +        <nvpair id="cib-bootstrap-options-cluster-name" name="cluster-name" value="test-cluster"/>
 | |
| +        <nvpair id="cib-bootstrap-options-stonith-enabled" name="stonith-enabled" value="true"/>
 | |
| +        <nvpair id="cib-bootstrap-options-maintenance-mode" name="maintenance-mode" value="false"/>
 | |
| +      </cluster_property_set>
 | |
| +    </crm_config>
 | |
| +    <nodes>
 | |
| +      <node id="1" uname="cluster01"/>
 | |
| +      <node id="2" uname="cluster02"/>
 | |
| +    </nodes>
 | |
| +    <resources>
 | |
| +      <primitive class="stonith" id="fencing" type="fence_xvm">
 | |
| +        <instance_attributes id="fencing-instance_attributes">
 | |
| +          <nvpair id="fencing-instance_attributes-ip_family" name="ip_family" value="ipv4"/>
 | |
| +        </instance_attributes>
 | |
| +        <operations/>
 | |
| +      </primitive>
 | |
| +      <primitive class="ocf" id="dummy-rsc" provider="pacemaker" type="Dummy">
 | |
| +        <instance_attributes id="dummy-rsc-instance_attributes">
 | |
| +          <nvpair id="dummy-rsc-instance_attributes-op_sleep" name="op_sleep" value="10"/>
 | |
| +        </instance_attributes>
 | |
| +        <operations/>
 | |
| +      </primitive>
 | |
| +      <primitive class="ocf" id="ping-rsc-ping" provider="pacemaker" type="ping">
 | |
| +        <instance_attributes id="ping-rsc-instance_attributes">
 | |
| +          <nvpair id="ping-rsc-host_list" name="host_list" value="4.2.2.2"/>
 | |
| +        </instance_attributes>
 | |
| +        <operations/>
 | |
| +      </primitive>
 | |
| +    </resources>
 | |
| +    <constraints/>
 | |
| +    <tags/>
 | |
| +    <rsc_defaults>
 | |
| +      <meta_attributes id="op-unmanaged">
 | |
| +        <rule id="op-unmanaged-rule" score="INFINITY">
 | |
| +            <rsc_expression id="op-unmanaged-expr" class="ocf" provider="pacemaker"/>
 | |
| +        </rule>
 | |
| +        <nvpair id="op-unmanaged-nvpair" name="is-managed" value="false"/>
 | |
| +      </meta_attributes>
 | |
| +    </rsc_defaults>
 | |
| +  </configuration>
 | |
| +  <status>
 | |
| +    <node_state id="1" uname="cluster01" in_ccm="true" crmd="online" crm-debug-origin="do_state_transition" join="member" expected="member"/>
 | |
| +    <node_state id="2" uname="cluster02" in_ccm="true" crmd="online" crm-debug-origin="do_update_resource" join="member" expected="member"/>
 | |
| +  </status>
 | |
| +</cib>
 | |
| -- 
 | |
| 1.8.3.1
 | |
| 
 |