Skip to content

Commit

Permalink
Merge pull request #1063 from igor-tsiglyar/versioned-params
Browse files Browse the repository at this point in the history
Feature: add versioned parameters support
  • Loading branch information
kgaillot committed Jul 26, 2016
2 parents e09c46c + 65d0b80 commit 0a8fef2
Show file tree
Hide file tree
Showing 18 changed files with 480 additions and 31 deletions.
35 changes: 33 additions & 2 deletions crmd/lrm.c
Expand Up @@ -628,9 +628,18 @@ build_parameter_list(lrmd_event_data_t *op, xmlNode *metadata, xmlNode *result,

if(result && accept) {
value = g_hash_table_lookup(op->params, name);

if(value != NULL) {
crm_trace("Adding attr %s=%s to the xml result", name, value);
crm_xml_add(result, name, value);
char *summary = crm_versioned_param_summary(op->versioned_params, name);

if (summary) {
crm_trace("Adding attr %s=%s to the xml result", name, summary);
crm_xml_add(result, name, summary);
free(summary);
} else {
crm_trace("Adding attr %s=%s to the xml result", name, value);
crm_xml_add(result, name, value);
}
}
}
}
Expand Down Expand Up @@ -1788,6 +1797,7 @@ construct_op(lrm_state_t * lrm_state, xmlNode * rsc_op, const char *rsc_id, cons
const char *op_timeout = NULL;
const char *op_interval = NULL;
GHashTable *params = NULL;
xmlNode *versioned_params = NULL;

const char *transition = NULL;

Expand Down Expand Up @@ -1822,6 +1832,14 @@ construct_op(lrm_state_t * lrm_state, xmlNode * rsc_op, const char *rsc_id, cons

params = xml2list(rsc_op);
g_hash_table_remove(params, CRM_META "_op_target_rc");

if (!is_remote_lrmd_ra(NULL, NULL, rsc_id)) {
xmlNode *ptr = first_named_child(rsc_op, XML_TAG_VER_ATTRS);

if (ptr) {
versioned_params = copy_xml(ptr);
}
}

op_delay = crm_meta_value(params, XML_OP_ATTR_START_DELAY);
op_timeout = crm_meta_value(params, XML_ATTR_TIMEOUT);
Expand All @@ -1833,6 +1851,7 @@ construct_op(lrm_state_t * lrm_state, xmlNode * rsc_op, const char *rsc_id, cons

if (safe_str_neq(operation, RSC_STOP)) {
op->params = params;
op->versioned_params = versioned_params;

} else {
rsc_history_t *entry = g_hash_table_lookup(lrm_state->resource_history, rsc_id);
Expand All @@ -1841,6 +1860,7 @@ construct_op(lrm_state_t * lrm_state, xmlNode * rsc_op, const char *rsc_id, cons
* whatever we are given */
if (!entry || !entry->stop_params) {
op->params = params;
op->versioned_params = versioned_params;
} else {
/* Copy the cached parameter list so that we stop the resource
* with the old attributes, not the new ones */
Expand All @@ -1851,6 +1871,17 @@ construct_op(lrm_state_t * lrm_state, xmlNode * rsc_op, const char *rsc_id, cons
g_hash_table_foreach(entry->stop_params, copy_instance_keys, op->params);
g_hash_table_destroy(params);
params = NULL;

op->versioned_params = NULL;
free_xml(versioned_params);
}
}

if (op->versioned_params) {
char *versioned_params_text = dump_xml_unformatted(op->versioned_params);

if (versioned_params_text) {
g_hash_table_insert(op->params, strdup("#" XML_TAG_VER_ATTRS), versioned_params_text);
}
}

Expand Down
4 changes: 4 additions & 0 deletions include/crm/lrmd.h
Expand Up @@ -237,6 +237,10 @@ typedef struct lrmd_event_data_s {
/*! exit failure reason string from resource agent operation */
const char *exit_reason;

/* This is an xmlNode containing the versioned parameters
* that should be evaluated */
xmlNode *versioned_params;

} lrmd_event_data_t;

lrmd_event_data_t *lrmd_copy_event(lrmd_event_data_t * event);
Expand Down
1 change: 1 addition & 0 deletions include/crm/msg_xml.h
Expand Up @@ -176,6 +176,7 @@
# define XML_TAG_ATTR_SETS "instance_attributes"
# define XML_TAG_META_SETS "meta_attributes"
# define XML_TAG_ATTRS "attributes"
# define XML_TAG_VER_ATTRS "versioned_attributes"
# define XML_TAG_PARAMS "parameters"
# define XML_TAG_PARAM "param"
# define XML_TAG_UTILIZATION "utilization"
Expand Down
3 changes: 3 additions & 0 deletions include/crm/pengine/complex.h
Expand Up @@ -56,6 +56,9 @@ void get_meta_attributes(GHashTable * meta_hash, resource_t * rsc, node_t * node
void get_rsc_attributes(GHashTable * meta_hash, resource_t * rsc, node_t * node,
pe_working_set_t * data_set);

void pe_get_versioned_attributes(xmlNode * meta_hash, resource_t * rsc, node_t * node,
pe_working_set_t * data_set);

typedef struct resource_alloc_functions_s resource_alloc_functions_t;

gboolean is_parent(resource_t *child, resource_t *rsc);
Expand Down
6 changes: 5 additions & 1 deletion include/crm/pengine/rules.h
Expand Up @@ -30,7 +30,8 @@ enum expression_type {
attr_expr,
loc_expr,
role_expr,
time_expr
time_expr,
version_expr
};

typedef struct pe_re_match_data {
Expand Down Expand Up @@ -58,6 +59,9 @@ void unpack_instance_attributes(xmlNode * top, xmlNode * xml_obj, const char *se
GHashTable * node_hash, GHashTable * hash,
const char *always_first, gboolean overwrite, crm_time_t * now);

void pe_unpack_versioned_attributes(xmlNode * top, xmlNode * xml_obj, const char *set_name,
GHashTable * node_hash, xmlNode * hash, crm_time_t * now);

char *pe_expand_re_matches(const char *string, pe_re_match_data_t * match_data);

#endif
2 changes: 2 additions & 0 deletions include/crm/pengine/status.h
Expand Up @@ -301,6 +301,8 @@ struct resource_s {
int remote_reconnect_interval;

pe_working_set_t *cluster;

xmlNode *versioned_parameters;
};

struct pe_action_s {
Expand Down
2 changes: 2 additions & 0 deletions include/crm_internal.h
Expand Up @@ -369,4 +369,6 @@ void remote_proxy_end_session(const char *session);
void remote_proxy_free(gpointer data);
int remote_proxy_check(lrmd_t * lrmd, GHashTable *hash);

char* crm_versioned_param_summary(xmlNode *versioned_params, const char *name);
void crm_summarize_versioned_params(xmlNode *param_set, xmlNode *versioned_params);
#endif /* CRM_INTERNAL__H */
66 changes: 66 additions & 0 deletions lib/common/digest.c
Expand Up @@ -240,3 +240,69 @@ crm_digest_verify(xmlNode *input, const char *expected)
free(calculated);
return passed;
}

char*
crm_versioned_param_summary(xmlNode *versioned_params, const char *name)
{
xmlNode *attrs = NULL;
xmlNode *attr = NULL;
char *summary = NULL;
gboolean found = FALSE;

if (!name) {
return NULL;
}

for (attrs = __xml_first_child(versioned_params); attrs != NULL; attrs = __xml_next_element(attrs)) {
for (attr = __xml_first_child(attrs); attr != NULL; attr = __xml_next_element(attr)) {
if (safe_str_eq((const char*) attr->name, XML_TAG_RULE)) {
const char *boolean_op = crm_element_value(attr, XML_RULE_ATTR_BOOLEAN_OP);
xmlNode *expr = NULL;

if (boolean_op == NULL) {
boolean_op = "and";
}
summary = add_list_element(summary, boolean_op);

for (expr = __xml_first_child(attr); expr != NULL; expr = __xml_next_element(expr)) {
summary = add_list_element(summary, crm_element_value(expr, XML_EXPR_ATTR_OPERATION));
summary = add_list_element(summary, crm_element_value(expr, XML_EXPR_ATTR_VALUE));
}
} else if (safe_str_eq(crm_element_value(attr, XML_NVPAIR_ATTR_NAME), name)) {
found = TRUE;
summary = add_list_element(summary, crm_element_value(attr, XML_NVPAIR_ATTR_VALUE));
break;
}
}
}

if (!found) {
free(summary);
return NULL;
}

return summary;
}

void
crm_summarize_versioned_params(xmlNode *param_set, xmlNode *versioned_params)
{
xmlNode *attrs = NULL;
xmlNode *attr = NULL;

if (!param_set) {
return;
}

for (attrs = __xml_first_child(versioned_params); attrs != NULL; attrs = __xml_next_element(attrs)) {
for (attr = __xml_first_child(attrs); attr != NULL; attr = __xml_next_element(attr)) {
const char *attr_name = crm_element_value(attr, XML_NVPAIR_ATTR_NAME);

if (attr_name) {
char *summary = crm_versioned_param_summary(versioned_params, attr_name);
crm_xml_replace(param_set, attr_name, summary);
free(summary);
}
}
}
}
1 change: 1 addition & 0 deletions lib/common/utils.c
Expand Up @@ -1715,6 +1715,7 @@ append_digest(lrmd_event_data_t * op, xmlNode * update, const char *version, con
args_xml = create_xml_node(NULL, XML_TAG_PARAMS);
g_hash_table_foreach(op->params, hash2field, args_xml);
filter_action_parameters(args_xml, version);
crm_summarize_versioned_params(args_xml, op->versioned_params);
digest = calculate_operation_digest(args_xml, version);

#if 0
Expand Down
19 changes: 18 additions & 1 deletion lib/lrmd/lrmd_client.c
Expand Up @@ -220,6 +220,10 @@ lrmd_copy_event(lrmd_event_data_t * event)
}
}

if (event->versioned_params) {
copy->versioned_params = copy_xml(event->versioned_params);
}

return copy;
}

Expand All @@ -240,6 +244,9 @@ lrmd_free_event(lrmd_event_data_t * event)
if (event->params) {
g_hash_table_destroy(event->params);
}
if (event->versioned_params) {
free_xml(event->versioned_params);
}
free(event);
}

Expand Down Expand Up @@ -290,6 +297,7 @@ lrmd_dispatch_internal(lrmd_t * lrmd, xmlNode * msg)
event.type = lrmd_event_exec_complete;

event.params = xml2list(msg);
event.versioned_params = first_named_child(msg, XML_TAG_VER_ATTRS);
} else if (crm_str_eq(type, LRMD_OP_NEW_CLIENT, TRUE)) {
event.type = lrmd_event_new_client;
} else if (crm_str_eq(type, LRMD_OP_POKE, TRUE)) {
Expand Down Expand Up @@ -1991,6 +1999,7 @@ lrmd_api_exec(lrmd_t * lrmd, const char *rsc_id, const char *action, const char
xmlNode *data = create_xml_node(NULL, F_LRMD_RSC);
xmlNode *args = create_xml_node(data, XML_TAG_ATTRS);
lrmd_key_value_t *tmp = NULL;
const char *versioned_args_key = "#" XML_TAG_VER_ATTRS;

crm_xml_add(data, F_LRMD_ORIGIN, __FUNCTION__);
crm_xml_add(data, F_LRMD_RSC_ID, rsc_id);
Expand All @@ -2001,7 +2010,15 @@ lrmd_api_exec(lrmd_t * lrmd, const char *rsc_id, const char *action, const char
crm_xml_add_int(data, F_LRMD_RSC_START_DELAY, start_delay);

for (tmp = params; tmp; tmp = tmp->next) {
hash2smartfield((gpointer) tmp->key, (gpointer) tmp->value, args);
if (safe_str_eq(tmp->key, versioned_args_key)) {
xmlNode *versioned_args = string2xml(tmp->value);

if (versioned_args) {
add_node_nocopy(data, NULL, versioned_args);
}
} else {
hash2smartfield((gpointer) tmp->key, (gpointer) tmp->value, args);
}
}

rc = lrmd_send_command(lrmd, LRMD_OP_RSC_EXEC, data, NULL, timeout, options, TRUE);
Expand Down
30 changes: 30 additions & 0 deletions lib/pengine/complex.c
Expand Up @@ -173,6 +173,30 @@ get_rsc_attributes(GHashTable * meta_hash, resource_t * rsc,
}
}

void
pe_get_versioned_attributes(xmlNode * meta_hash, resource_t * rsc,
node_t * node, pe_working_set_t * data_set)
{
GHashTable *node_hash = NULL;

if (node) {
node_hash = node->details->attrs;
}

pe_unpack_versioned_attributes(data_set->input, rsc->xml, XML_TAG_ATTR_SETS, node_hash,
meta_hash, data_set->now);

/* set anything else based on the parent */
if (rsc->parent != NULL) {
pe_get_versioned_attributes(meta_hash, rsc->parent, node, data_set);

} else {
/* and finally check the defaults */
pe_unpack_versioned_attributes(data_set->input, data_set->rsc_defaults, XML_TAG_ATTR_SETS,
node_hash, meta_hash, data_set->now);
}
}

static char *
template_op_key(xmlNode * op)
{
Expand Down Expand Up @@ -437,6 +461,8 @@ common_unpack(xmlNode * xml_obj, resource_t ** rsc,
(*rsc)->parameters =
g_hash_table_new_full(crm_str_hash, g_str_equal, g_hash_destroy_str, g_hash_destroy_str);

(*rsc)->versioned_parameters = create_xml_node(NULL, XML_TAG_VER_ATTRS);

(*rsc)->meta =
g_hash_table_new_full(crm_str_hash, g_str_equal, g_hash_destroy_str, g_hash_destroy_str);

Expand All @@ -459,6 +485,7 @@ common_unpack(xmlNode * xml_obj, resource_t ** rsc,

get_meta_attributes((*rsc)->meta, *rsc, NULL, data_set);
get_rsc_attributes((*rsc)->parameters, *rsc, NULL, data_set);
pe_get_versioned_attributes((*rsc)->versioned_parameters, *rsc, NULL, data_set);

(*rsc)->flags = 0;
set_bit((*rsc)->flags, pe_rsc_runnable);
Expand Down Expand Up @@ -808,6 +835,9 @@ common_free(resource_t * rsc)
if (rsc->parameters != NULL) {
g_hash_table_destroy(rsc->parameters);
}
if (rsc->versioned_parameters != NULL) {
free_xml(rsc->versioned_parameters);
}
if (rsc->meta != NULL) {
g_hash_table_destroy(rsc->meta);
}
Expand Down

0 comments on commit 0a8fef2

Please sign in to comment.