29 #define VARIANT_CONTAINER 1 35 next_ip(
const char *last_ip)
37 unsigned int oct1 = 0;
38 unsigned int oct2 = 0;
39 unsigned int oct3 = 0;
40 unsigned int oct4 = 0;
41 int rc = sscanf(last_ip,
"%u.%u.%u.%u", &oct1, &oct2, &oct3, &oct4);
47 }
else if (oct3 > 253) {
50 }
else if (oct4 > 253) {
62 allocate_ip(container_variant_data_t *
data, container_grouping_t *tuple,
char *buffer,
int max)
64 if(data->ip_range_start == NULL) {
67 }
else if(data->ip_last) {
68 tuple->ipaddr = next_ip(data->ip_last);
71 tuple->ipaddr = strdup(data->ip_range_start);
74 data->ip_last = tuple->ipaddr;
76 return snprintf(buffer, max,
" --add-host=%s-%d:%s --link %s-docker-%d:%s-link-%d",
77 data->prefix, tuple->offset, tuple->ipaddr,
78 data->prefix, tuple->offset, data->prefix, tuple->offset);
80 if (data->type == PE_CONTAINER_TYPE_DOCKER) {
81 return snprintf(buffer, max,
" --add-host=%s-%d:%s",
82 data->prefix, tuple->offset, tuple->ipaddr);
83 }
else if (data->type == PE_CONTAINER_TYPE_RKT) {
84 return snprintf(buffer, max,
" --hosts-entry=%s=%s-%d",
85 tuple->ipaddr, data->prefix, tuple->offset);
93 create_resource(
const char *name,
const char *provider,
const char *kind)
118 valid_network(container_variant_data_t *data)
120 if(data->ip_range_start) {
123 if(data->control_port) {
124 if(data->replicas_per_host > 1) {
125 pe_err(
"Specifying the 'control-port' for %s requires 'replicas-per-host=1'", data->prefix);
126 data->replicas_per_host = 1;
136 resource_t *parent, container_variant_data_t *data, container_grouping_t *tuple,
139 if(data->ip_range_start) {
141 xmlNode *xml_ip = NULL;
142 xmlNode *xml_obj = NULL;
146 xml_ip = create_resource(
id,
"heartbeat",
"IPaddr2");
150 crm_xml_set_id(xml_obj,
"%s-attributes-%d", data->prefix, tuple->offset);
153 if(data->host_network) {
157 if(data->host_netmask) {
159 "cidr_netmask", data->host_netmask);
170 if (
common_unpack(xml_ip, &tuple->ip, parent, data_set) ==
false) {
180 create_docker_resource(
181 resource_t *parent, container_variant_data_t *data, container_grouping_t *tuple,
184 int offset = 0, max = 4096;
185 char *buffer = calloc(1, max+1);
187 int doffset = 0, dmax = 1024;
188 char *dbuffer = calloc(1, dmax+1);
191 xmlNode *xml_docker = NULL;
192 xmlNode *xml_obj = NULL;
196 xml_docker = create_resource(
id,
"heartbeat",
"docker");
200 crm_xml_set_id(xml_obj,
"%s-attributes-%d", data->prefix, tuple->offset);
207 offset += snprintf(buffer+offset, max-offset,
" --restart=no");
214 if (data->ip_range_start != NULL) {
215 offset += snprintf(buffer+offset, max-offset,
" -h %s-%d",
216 data->prefix, tuple->offset);
219 if(data->docker_network) {
221 offset += snprintf(buffer+offset, max-offset,
" --net=%s", data->docker_network);
224 if(data->control_port) {
225 offset += snprintf(buffer+offset, max-offset,
" -e PCMK_remote_port=%s", data->control_port);
227 offset += snprintf(buffer+offset, max-offset,
" -e PCMK_remote_port=%d",
DEFAULT_REMOTE_PORT);
230 for(
GListPtr pIter = data->mounts; pIter != NULL; pIter = pIter->next) {
231 container_mount_t *mount = pIter->data;
235 "%s/%s-%d", mount->source, data->prefix, tuple->offset);
238 doffset += snprintf(dbuffer+doffset, dmax-doffset,
",");
240 doffset += snprintf(dbuffer+doffset, dmax-doffset,
"%s", source);
241 offset += snprintf(buffer+offset, max-offset,
" -v %s:%s", source, mount->target);
245 offset += snprintf(buffer+offset, max-offset,
" -v %s:%s", mount->source, mount->target);
248 offset += snprintf(buffer+offset, max-offset,
":%s", mount->options);
252 for(
GListPtr pIter = data->ports; pIter != NULL; pIter = pIter->next) {
253 container_port_t *port = pIter->data;
256 offset += snprintf(buffer+offset, max-offset,
" -p %s:%s:%s",
257 tuple->ipaddr, port->source, port->target);
259 offset += snprintf(buffer+offset, max-offset,
" -p %s:%s", port->source, port->target);
263 if(data->docker_run_options) {
264 offset += snprintf(buffer+offset, max-offset,
" %s", data->docker_run_options);
267 if(data->docker_host_options) {
268 offset += snprintf(buffer+offset, max-offset,
" %s", data->docker_host_options);
278 if(data->docker_run_command) {
280 "run_cmd", data->docker_run_command);
283 "run_cmd",
SBIN_DIR "/pacemaker_remoted");
307 if(data->docker_run_command) {
309 "run_cmd", data->docker_run_command);
326 if (
common_unpack(xml_docker, &tuple->docker, parent, data_set) == FALSE) {
335 resource_t *parent, container_variant_data_t *data, container_grouping_t *tuple,
338 int offset = 0, max = 4096;
339 char *buffer = calloc(1, max+1);
341 int doffset = 0, dmax = 1024;
342 char *dbuffer = calloc(1, dmax+1);
345 xmlNode *xml_docker = NULL;
346 xmlNode *xml_obj = NULL;
352 xml_docker = create_resource(
id,
"heartbeat",
"rkt");
356 crm_xml_set_id(xml_obj,
"%s-attributes-%d", data->prefix, tuple->offset);
368 if (data->ip_range_start != NULL) {
369 offset += snprintf(buffer+offset, max-offset,
" --hostname=%s-%d",
370 data->prefix, tuple->offset);
373 if(data->docker_network) {
375 offset += snprintf(buffer+offset, max-offset,
" --net=%s", data->docker_network);
378 if(data->control_port) {
379 offset += snprintf(buffer+offset, max-offset,
" --environment=PCMK_remote_port=%s", data->control_port);
381 offset += snprintf(buffer+offset, max-offset,
" --environment=PCMK_remote_port=%d",
DEFAULT_REMOTE_PORT);
384 for(
GListPtr pIter = data->mounts; pIter != NULL; pIter = pIter->next) {
385 container_mount_t *mount = pIter->data;
389 "%s/%s-%d", mount->source, data->prefix, tuple->offset);
392 doffset += snprintf(dbuffer+doffset, dmax-doffset,
",");
394 doffset += snprintf(dbuffer+doffset, dmax-doffset,
"%s", source);
395 offset += snprintf(buffer+offset, max-offset,
" --volume vol%d,kind=host,source=%s", volid, source);
397 offset += snprintf(buffer+offset, max-offset,
",%s", mount->options);
399 offset += snprintf(buffer+offset, max-offset,
" --mount volume=vol%d,target=%s", volid, mount->target);
403 offset += snprintf(buffer+offset, max-offset,
" --volume vol%d,kind=host,source=%s", volid, mount->source);
405 offset += snprintf(buffer+offset, max-offset,
",%s", mount->options);
407 offset += snprintf(buffer+offset, max-offset,
" --mount volume=vol%d,target=%s", volid, mount->target);
412 for(
GListPtr pIter = data->ports; pIter != NULL; pIter = pIter->next) {
413 container_port_t *port = pIter->data;
416 offset += snprintf(buffer+offset, max-offset,
" --port=%s:%s:%s",
417 port->target, tuple->ipaddr, port->source);
419 offset += snprintf(buffer+offset, max-offset,
" --port=%s:%s", port->target, port->source);
423 if(data->docker_run_options) {
424 offset += snprintf(buffer+offset, max-offset,
" %s", data->docker_run_options);
427 if(data->docker_host_options) {
428 offset += snprintf(buffer+offset, max-offset,
" %s", data->docker_host_options);
438 if(data->docker_run_command) {
465 if(data->docker_run_command) {
467 data->docker_run_command);
484 if (
common_unpack(xml_docker, &tuple->docker, parent, data_set) == FALSE) {
500 gpointer match = g_hash_table_lookup(rsc->
allowed_nodes, uname);
509 for (child = rsc->
children; child != NULL; child = child->next) {
510 disallow_node((
resource_t *) (child->data), uname);
516 create_remote_resource(
517 resource_t *parent, container_variant_data_t *data, container_grouping_t *tuple,
520 if (tuple->child && valid_network(data)) {
524 xmlNode *xml_remote = NULL;
527 const char *uname = NULL;
528 const char *connect_name = NULL;
533 id =
crm_strdup_printf(
"pcmk-internal-%s-remote-%d", tuple->child->id, tuple->offset);
541 connect_name = (tuple->ipaddr? tuple->ipaddr :
"#uname");
543 if (data->control_port == NULL) {
556 data->control_port : port_s));
565 uname =
ID(xml_remote);
597 for (rsc_iter = data_set->
resources; rsc_iter; rsc_iter = rsc_iter->next) {
598 disallow_node((
resource_t *) (rsc_iter->data), uname);
602 tuple->node->weight = 500;
606 g_hash_table_insert(tuple->child->allowed_nodes, (gpointer) tuple->node->details->id,
node_copy(tuple->node));
608 if (
common_unpack(xml_remote, &tuple->remote, parent, data_set) == FALSE) {
612 g_hash_table_iter_init(&gIter, tuple->remote->allowed_nodes);
613 while (g_hash_table_iter_next(&gIter, NULL, (
void **)&node)) {
620 tuple->node->details->remote_rsc = tuple->remote;
625 g_hash_table_insert(tuple->node->details->attrs,
644 resource_t *parent, container_variant_data_t *data, container_grouping_t *tuple,
648 if (data->type == PE_CONTAINER_TYPE_DOCKER &&
649 create_docker_resource(parent, data, tuple, data_set) == FALSE) {
652 if (data->type == PE_CONTAINER_TYPE_RKT &&
653 create_rkt_resource(parent, data, tuple, data_set) == FALSE) {
657 if(create_ip_resource(parent, data, tuple, data_set) == FALSE) {
660 if(create_remote_resource(parent, data, tuple, data_set) == FALSE) {
663 if(tuple->child && tuple->ipaddr) {
684 mount_add(container_variant_data_t *container_data,
const char *source,
685 const char *target,
const char *options,
int flags)
687 container_mount_t *mount = calloc(1,
sizeof(container_mount_t));
689 mount->source = strdup(source);
690 mount->target = strdup(target);
692 mount->options = strdup(options);
694 mount->flags =
flags;
695 container_data->mounts = g_list_append(container_data->mounts, mount);
698 static void mount_free(container_mount_t *mount)
702 free(mount->options);
706 static void port_free(container_port_t *port)
716 const char *value = NULL;
717 xmlNode *xml_obj = NULL;
718 xmlNode *xml_resource = NULL;
719 container_variant_data_t *container_data = NULL;
724 container_data = calloc(1,
sizeof(container_variant_data_t));
726 container_data->prefix = strdup(rsc->
id);
729 if (xml_obj != NULL) {
730 container_data->type = PE_CONTAINER_TYPE_DOCKER;
733 if (xml_obj != NULL) {
734 container_data->type = PE_CONTAINER_TYPE_RKT;
742 if (container_data->masters < 0) {
743 pe_err(
"'masters' for %s must be nonnegative integer, using 0",
745 container_data->masters = 0;
749 if ((value == NULL) && (container_data->masters > 0)) {
750 container_data->replicas = container_data->masters;
754 if (container_data->replicas < 1) {
755 pe_err(
"'replicas' for %s must be positive integer, using 1", rsc->
id);
756 container_data->replicas = 1;
765 container_data->replicas_per_host =
crm_parse_int(value,
"1");
766 if (container_data->replicas_per_host < 1) {
767 pe_err(
"'replicas-per-host' for %s must be positive integer, using 1",
769 container_data->replicas_per_host = 1;
771 if (container_data->replicas_per_host == 1) {
788 for (xmlNode *xml_child = __xml_first_child_element(xml_obj); xml_child != NULL;
789 xml_child = __xml_next_element(xml_child)) {
791 container_port_t *port = calloc(1,
sizeof(container_port_t));
794 if(port->source == NULL) {
800 if(port->source != NULL && strlen(port->source) > 0) {
801 if(port->target == NULL) {
802 port->target = strdup(port->source);
804 container_data->ports = g_list_append(container_data->ports, port);
807 pe_err(
"Invalid port directive %s",
ID(xml_child));
814 for (xmlNode *xml_child = __xml_first_child_element(xml_obj); xml_child != NULL;
815 xml_child = __xml_next_element(xml_child)) {
822 if (source == NULL) {
827 if (source && target) {
828 mount_add(container_data, source, target, options, flags);
830 pe_err(
"Invalid mount directive %s",
ID(xml_child));
835 if (xml_obj && valid_network(container_data)) {
837 xmlNode *xml_set = NULL;
839 if(container_data->masters > 0) {
846 crm_xml_set_id(xml_resource,
"%s-%s", container_data->prefix, xml_resource->name);
849 crm_xml_set_id(xml_set,
"%s-%s-meta", container_data->prefix, xml_resource->name);
854 value =
crm_itoa(container_data->replicas);
859 value =
crm_itoa(container_data->replicas_per_host);
865 (container_data->replicas_per_host > 1)?
868 if(container_data->masters) {
869 value =
crm_itoa(container_data->masters);
879 pe_err(
"Cannot control %s inside %s without either ip-range-start or control-port",
880 rsc->
id,
ID(xml_obj));
888 container_port_t *port = NULL;
889 const char *key_loc = NULL;
891 int offset = 0, max = 1024;
894 if (
common_unpack(xml_resource, &new_rsc, rsc, data_set) == FALSE) {
895 pe_err(
"Failed unpacking resource %s",
ID(rsc->
xml));
896 if (new_rsc != NULL && new_rsc->
fns != NULL) {
902 container_data->child = new_rsc;
924 key_loc = getenv(
"PCMK_authkey_location");
925 if (key_loc == NULL) {
931 mount_add(container_data,
CRM_LOG_DIR "/bundles",
"/var/log", NULL, 1);
933 port = calloc(1,
sizeof(container_port_t));
934 if(container_data->control_port) {
935 port->source = strdup(container_data->control_port);
947 port->target = strdup(port->source);
948 container_data->ports = g_list_append(container_data->ports, port);
950 buffer = calloc(1, max+1);
951 for(childIter = container_data->child->children; childIter != NULL; childIter = childIter->next) {
952 container_grouping_t *tuple = calloc(1,
sizeof(container_grouping_t));
953 tuple->child = childIter->data;
954 tuple->offset = lpc++;
961 offset += allocate_ip(container_data, tuple, buffer+offset, max-offset);
962 container_data->tuples = g_list_append(container_data->tuples, tuple);
963 container_data->attribute_target = g_hash_table_lookup(tuple->child->meta,
XML_RSC_ATTR_TARGET);
965 container_data->docker_host_options = buffer;
966 if(container_data->attribute_target) {
968 g_hash_table_replace(container_data->child->meta, strdup(
XML_RSC_ATTR_TARGET), strdup(container_data->attribute_target));
973 int offset = 0, max = 1024;
974 char *buffer = calloc(1, max+1);
976 for(
int lpc = 0; lpc < container_data->replicas; lpc++) {
977 container_grouping_t *tuple = calloc(1,
sizeof(container_grouping_t));
979 offset += allocate_ip(container_data, tuple, buffer+offset, max-offset);
980 container_data->tuples = g_list_append(container_data->tuples, tuple);
983 container_data->docker_host_options = buffer;
986 for (
GListPtr gIter = container_data->tuples; gIter != NULL; gIter = gIter->next) {
987 container_grouping_t *tuple = (container_grouping_t *)gIter->data;
988 if (create_container(rsc, container_data, tuple, data_set) == FALSE) {
989 pe_err(
"Failed unpacking resource %s", rsc->
id);
995 if(container_data->child) {
1002 tuple_rsc_active(
resource_t *rsc, gboolean all)
1005 gboolean child_active = rsc->
fns->
active(rsc, all);
1007 if (child_active && !all) {
1009 }
else if (!child_active && all) {
1019 container_variant_data_t *container_data = NULL;
1022 get_container_variant_data(container_data, rsc);
1023 for (iter = container_data->tuples; iter != NULL; iter = iter->next) {
1024 container_grouping_t *tuple = (container_grouping_t *)(iter->data);
1027 rsc_active = tuple_rsc_active(tuple->ip, all);
1028 if (rsc_active >= 0) {
1029 return (gboolean) rsc_active;
1032 rsc_active = tuple_rsc_active(tuple->child, all);
1033 if (rsc_active >= 0) {
1034 return (gboolean) rsc_active;
1037 rsc_active = tuple_rsc_active(tuple->docker, all);
1038 if (rsc_active >= 0) {
1039 return (gboolean) rsc_active;
1042 rsc_active = tuple_rsc_active(tuple->remote, all);
1043 if (rsc_active >= 0) {
1044 return (gboolean) rsc_active;
1058 container_variant_data_t *container_data = NULL;
1063 get_container_variant_data(container_data, parent);
1066 for (
GListPtr gIter = container_data->tuples; gIter != NULL; gIter = gIter->next) {
1067 container_grouping_t *tuple = (container_grouping_t *)gIter->data;
1070 if(tuple->node->details == node->
details) {
1086 print_rsc_in_list(
resource_t *rsc,
const char *pre_text,
long options,
1093 rsc->
fns->
print(rsc, pre_text, options, print_data);
1094 if (options & pe_print_html) {
1101 container_type_as_string(
enum container_type t)
1103 if (t == PE_CONTAINER_TYPE_DOCKER) {
1104 return PE_CONTAINER_TYPE_DOCKER_S;
1105 }
else if (t == PE_CONTAINER_TYPE_RKT) {
1106 return PE_CONTAINER_TYPE_RKT_S;
1108 return PE_CONTAINER_TYPE_UNKNOWN_S;
1113 container_print_xml(
resource_t * rsc,
const char *pre_text,
long options,
void *print_data)
1115 container_variant_data_t *container_data = NULL;
1116 char *child_text = NULL;
1119 if (pre_text == NULL) {
1124 get_container_variant_data(container_data, rsc);
1131 for (
const char *c = container_type_as_string(container_data->type);
1143 for (
GListPtr gIter = container_data->tuples; gIter != NULL; gIter = gIter->next) {
1144 container_grouping_t *tuple = (container_grouping_t *)gIter->data;
1147 status_print(
"%s <replica id=\"%d\">\n", pre_text, tuple->offset);
1148 print_rsc_in_list(tuple->ip, child_text, options, print_data);
1149 print_rsc_in_list(tuple->child, child_text, options, print_data);
1150 print_rsc_in_list(tuple->docker, child_text, options, print_data);
1151 print_rsc_in_list(tuple->remote, child_text, options, print_data);
1159 tuple_print(container_grouping_t * tuple,
const char *pre_text,
long options,
void *print_data)
1165 char buffer[LINE_MAX];
1168 rsc = tuple->docker;
1172 offset += snprintf(buffer + offset, LINE_MAX - offset,
"%s",
rsc_printable_id(tuple->remote));
1174 offset += snprintf(buffer + offset, LINE_MAX - offset,
"%s",
rsc_printable_id(tuple->docker));
1177 offset += snprintf(buffer + offset, LINE_MAX - offset,
" (%s)", tuple->ipaddr);
1180 if (tuple->docker->running_on) {
1181 node = tuple->docker->running_on->data;
1183 common_print(rsc, pre_text, buffer, node, options, print_data);
1189 container_variant_data_t *container_data = NULL;
1190 char *child_text = NULL;
1194 container_print_xml(rsc, pre_text, options, print_data);
1198 get_container_variant_data(container_data, rsc);
1200 if (pre_text == NULL) {
1205 pre_text, container_type_as_string(container_data->type),
1206 container_data->replicas>1?
" set":
"", rsc->
id, container_data->image,
1214 for (
GListPtr gIter = container_data->tuples; gIter != NULL; gIter = gIter->next) {
1215 container_grouping_t *tuple = (container_grouping_t *)gIter->data;
1218 if (options & pe_print_html) {
1224 if(g_list_length(container_data->tuples) > 1) {
1225 status_print(
" %sReplica[%d]\n", pre_text, tuple->offset);
1227 if (options & pe_print_html) {
1230 print_rsc_in_list(tuple->ip, child_text, options, print_data);
1231 print_rsc_in_list(tuple->docker, child_text, options, print_data);
1232 print_rsc_in_list(tuple->remote, child_text, options, print_data);
1233 print_rsc_in_list(tuple->child, child_text, options, print_data);
1234 if (options & pe_print_html) {
1239 tuple_print(tuple, child_text, options, print_data);
1243 if (options & pe_print_html) {
1247 if (options & pe_print_html) {
1266 tuple->ip->xml = NULL;
1267 tuple->ip->fns->free(tuple->ip);
1272 tuple->docker->xml = NULL;
1273 tuple->docker->fns->free(tuple->docker);
1274 tuple->docker = NULL;
1278 tuple->remote->xml = NULL;
1279 tuple->remote->fns->free(tuple->remote);
1280 tuple->remote = NULL;
1282 free(tuple->ipaddr);
1289 container_variant_data_t *container_data = NULL;
1292 get_container_variant_data(container_data, rsc);
1295 free(container_data->prefix);
1296 free(container_data->image);
1297 free(container_data->control_port);
1298 free(container_data->host_network);
1299 free(container_data->host_netmask);
1300 free(container_data->ip_range_start);
1301 free(container_data->docker_network);
1302 free(container_data->docker_run_options);
1303 free(container_data->docker_run_command);
1304 free(container_data->docker_host_options);
1306 g_list_free_full(container_data->tuples, (GDestroyNotify)
tuple_free);
1307 g_list_free_full(container_data->mounts, (GDestroyNotify)mount_free);
1308 g_list_free_full(container_data->ports, (GDestroyNotify)port_free);
1311 if(container_data->child) {
1312 free_xml(container_data->child->xml);
1313 container_data->child->xml = NULL;
1314 container_data->child->fns->free(container_data->child);
1323 return container_role;
1339 container_variant_data_t *container_data = NULL;
1341 get_container_variant_data(container_data, rsc);
1342 return container_data->replicas;
bool remote_id_conflict(const char *remote_name, pe_working_set_t *data)
#define CRM_CHECK(expr, failure_action)
gboolean safe_str_neq(const char *a, const char *b)
int pe_bundle_replicas(const resource_t *rsc)
Get the number of configured replicas in a bundle.
node_t * node_copy(const node_t *this_node)
node_t * pe_create_node(const char *id, const char *uname, const char *type, const char *score, pe_working_set_t *data_set)
void(* free)(resource_t *)
#define XML_BOOLEAN_FALSE
gboolean common_unpack(xmlNode *xml_obj, resource_t **rsc, resource_t *parent, pe_working_set_t *data_set)
enum pe_obj_types variant
void common_free(resource_t *rsc)
#define status_print(fmt, args...)
int crm_parse_int(const char *text, const char *default_text)
char * crm_element_value_copy(xmlNode *data, const char *name)
node_t * pe_find_node(GListPtr node_list, const char *uname)
resource_t * uber_parent(resource_t *rsc)
#define clear_bit(word, bit)
#define XML_RSC_ATTR_INCARNATION_MAX
#define XML_RSC_ATTR_TARGET
#define pe_rsc_allow_remote_remotes
void crm_xml_sanitize_id(char *id)
Sanitize a string so it is usable as an XML ID.
#define DEFAULT_REMOTE_PORT
#define DEFAULT_REMOTE_KEY_LOCATION
#define XML_TAG_ATTR_SETS
gboolean is_remote_node(node_t *node)
struct node_shared_s * details
#define set_bit(word, bit)
#define PCMK_RESOURCE_CLASS_OCF
xmlNode * pe_create_remote_xml(xmlNode *parent, const char *uname, const char *container_id, const char *migrateable, const char *is_managed, const char *interval, const char *monitor_timeout, const char *start_timeout, const char *server, const char *port)
#define XML_CIB_TAG_RESOURCE
resource_object_functions_t * fns
GHashTable * allowed_nodes
xmlNode * add_node_copy(xmlNode *new_parent, xmlNode *xml_node)
xmlNode * crm_create_op_xml(xmlNode *parent, const char *prefix, const char *task, const char *interval, const char *timeout)
Create a CIB XML element for an operation.
#define XML_AGENT_ATTR_PROVIDER
#define XML_RSC_ATTR_ORDERED
#define XML_TAG_META_SETS
xmlNode * create_xml_node(xmlNode *parent, const char *name)
const char * crm_element_value(xmlNode *data, const char *name)
#define XML_RSC_ATTR_INCARNATION_NODEMAX
void free_xml(xmlNode *child)
#define XML_RSC_ATTR_UNIQUE
gboolean(* active)(resource_t *, gboolean)
void common_print(resource_t *rsc, const char *pre_text, const char *name, node_t *node, long options, void *print_data)
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
#define XML_RSC_ATTR_MASTER_MAX
void(* print)(resource_t *, const char *, long, void *)
gboolean container_unpack(resource_t *rsc, pe_working_set_t *data_set)
enum rsc_role_e container_resource_state(const resource_t *rsc, gboolean current)
void tuple_free(container_grouping_t *tuple)
#define XML_CIB_TAG_INCARNATION
void add_hash_param(GHashTable *hash, const char *name, const char *value)
void crm_xml_set_id(xmlNode *xml, const char *format,...) __attribute__((__format__(__printf__
gboolean container_active(resource_t *rsc, gboolean all)
xmlNode * crm_create_nvpair_xml(xmlNode *parent, const char *id, const char *name, const char *value)
Create an XML name/value pair.
#define XML_CIB_TAG_MASTER
xmlNode * first_named_child(xmlNode *parent, const char *name)
#define pe_rsc_trace(rsc, fmt, args...)
char * crm_concat(const char *prefix, const char *suffix, char join)
char * crm_itoa(int an_int)
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
void container_print(resource_t *rsc, const char *pre_text, long options, void *print_data)
resource_t * find_container_child(const char *stem, resource_t *rsc, node_t *node)
const char * rsc_printable_id(resource_t *rsc)
#define XML_AGENT_ATTR_CLASS
void container_free(resource_t *rsc)