49 #define PE__CONTAINER_AGENT_UNKNOWN_S "unknown" 50 #define PE__CONTAINER_AGENT_DOCKER_S "docker" 51 #define PE__CONTAINER_AGENT_RKT_S "rkt" 52 #define PE__CONTAINER_AGENT_PODMAN_S "podman" 54 typedef struct pe__bundle_variant_data_s {
57 int nreplicas_per_host;
64 char *container_network;
67 gchar *container_host_options;
68 char *container_command;
69 char *launcher_options;
70 const char *attribute_target;
81 #define get_bundle_variant_data(data, rsc) \ 82 CRM_ASSERT(rsc != NULL); \ 83 CRM_ASSERT(rsc->variant == pcmk_rsc_variant_bundle); \ 84 CRM_ASSERT(rsc->variant_opaque != NULL); \ 85 data = (pe__bundle_variant_data_t *) rsc->variant_opaque; 101 return bundle_data->nreplicas;
118 return bundle_data->child;
141 for (
const GList *iter =
data->replicas; iter != NULL; iter = iter->next) {
145 return replica->
child;
167 for (GList *iter = bundle_data->replicas; iter != NULL; iter = iter->next) {
170 if (pe__same_node(node, replica->
node)) {
193 if (bundle_data->replicas == NULL) {
196 replica = bundle_data->replicas->data;
217 for (GList *iter = bundle_data->replicas; iter != NULL; iter = iter->next) {
242 for (
const GList *iter = bundle_data->replicas; iter != NULL;
252 next_ip(
const char *last_ip)
254 unsigned int oct1 = 0;
255 unsigned int oct2 = 0;
256 unsigned int oct3 = 0;
257 unsigned int oct4 = 0;
258 int rc = sscanf(last_ip,
"%u.%u.%u.%u", &oct1, &oct2, &oct3, &oct4);
264 }
else if (oct3 > 253) {
267 }
else if (oct4 > 253) {
282 if(
data->ip_range_start == NULL) {
285 }
else if(
data->ip_last) {
289 replica->
ipaddr = strdup(
data->ip_range_start);
293 switch (
data->agent_type) {
296 if (
data->add_host) {
297 g_string_append_printf(buffer,
" --add-host=%s-%d:%s",
301 g_string_append_printf(buffer,
" --hosts-entry=%s=%s-%d",
308 g_string_append_printf(buffer,
" --hosts-entry=%s=%s-%d",
319 create_resource(
const char *
name,
const char *provider,
const char *kind)
346 if(
data->ip_range_start) {
349 if(
data->control_port) {
350 if(
data->nreplicas_per_host > 1) {
351 pe_err(
"Specifying the 'control-port' for %s requires 'replicas-per-host=1'",
data->prefix);
352 data->nreplicas_per_host = 1;
365 if(
data->ip_range_start) {
367 xmlNode *xml_ip = NULL;
368 xmlNode *xml_obj = NULL;
372 xml_ip = create_resource(
id,
"heartbeat",
"IPaddr2");
380 if(
data->host_network) {
384 if(
data->host_netmask) {
386 "cidr_netmask",
data->host_netmask);
427 xmlNode *xml_container = NULL;
428 xmlNode *xml_obj = NULL;
431 const char *hostname_opt = NULL;
432 const char *env_opt = NULL;
433 const char *agent_str = NULL;
436 GString *buffer = NULL;
437 GString *dbuffer = NULL;
440 switch (
data->agent_type) {
443 hostname_opt =
"-h ";
447 hostname_opt =
"--hostname=";
448 env_opt =
"--environment=";
453 agent_str = container_agent_str(
data->agent_type);
455 buffer = g_string_sized_new(4096);
460 xml_container = create_resource(
id,
"heartbeat", agent_str);
472 g_string_append(buffer,
" --restart=no");
480 if (
data->ip_range_start != NULL) {
481 g_string_append_printf(buffer,
" %s%s-%d", hostname_opt,
data->prefix,
486 if (
data->container_network != NULL) {
490 if (
data->control_port != NULL) {
492 data->control_port, NULL);
498 for (GList *iter =
data->mounts; iter != NULL; iter = iter->next) {
499 pe__bundle_mount_t *mount = (pe__bundle_mount_t *) iter->data;
508 switch (
data->agent_type) {
512 " -v ", pcmk__s(source, mount->source),
513 ":", mount->target, NULL);
515 if (mount->options != NULL) {
520 g_string_append_printf(buffer,
521 " --volume vol%d,kind=host," 523 "--mount volume=vol%d,target=%s",
524 volid, pcmk__s(source, mount->source),
525 (mount->options != NULL)?
"," :
"",
526 pcmk__s(mount->options,
""),
527 volid, mount->target);
536 for (GList *iter =
data->ports; iter != NULL; iter = iter->next) {
537 pe__bundle_port_t *port = (pe__bundle_port_t *) iter->data;
539 switch (
data->agent_type) {
542 if (replica->
ipaddr != NULL) {
544 " -p ", replica->
ipaddr,
":", port->source,
545 ":", port->target, NULL);
547 }
else if (!pcmk__str_eq(
data->container_network,
"host",
551 " -p ", port->source,
":", port->target,
556 if (replica->
ipaddr != NULL) {
558 " --port=", port->target,
559 ":", replica->
ipaddr,
":", port->source,
563 " --port=", port->target,
":", port->source,
584 if (
data->launcher_options != NULL) {
588 if (
data->container_host_options != NULL) {
593 (
const char *) buffer->str);
594 g_string_free(buffer, TRUE);
597 (dbuffer != NULL)? (
const char *) dbuffer->str :
"");
598 if (dbuffer != NULL) {
599 g_string_free(dbuffer, TRUE);
602 if (replica->
child != NULL) {
603 if (
data->container_command != NULL) {
605 data->container_command);
624 }
else if ((child != NULL) &&
data->untrusted) {
631 if (
data->container_command != NULL) {
633 data->container_command);
675 g_list_foreach(rsc->
children, (GFunc) disallow_node, (gpointer)
uname);
683 if (replica->
child && valid_network(
data)) {
684 GHashTableIter gIter;
686 xmlNode *xml_remote = NULL;
689 const char *
uname = NULL;
690 const char *connect_name = NULL;
706 connect_name = (replica->
ipaddr? replica->
ipaddr :
"#uname");
708 if (
data->control_port == NULL) {
719 connect_name, (
data->control_port?
720 data->control_port : port_s));
761 g_list_foreach(
parent->cluster->resources, (GFunc) disallow_node,
789 while (g_hash_table_iter_next(&gIter, NULL, (
void **)&node)) {
827 rc = create_container_resource(
parent,
data, replica);
832 rc = create_ip_resource(
parent,
data, replica);
837 rc = create_remote_resource(
parent,
data, replica);
842 if ((replica->
child != NULL) && (replica->
ipaddr != NULL)) {
846 if (replica->
remote != NULL) {
863 const char *
target,
const char *options, uint32_t
flags)
865 pe__bundle_mount_t *mount = calloc(1,
sizeof(pe__bundle_mount_t));
868 mount->source = strdup(source);
869 mount->target = strdup(
target);
871 mount->flags =
flags;
872 bundle_data->mounts = g_list_append(bundle_data->mounts, mount);
876 mount_free(pe__bundle_mount_t *mount)
880 free(mount->options);
885 port_free(pe__bundle_port_t *port)
902 while (top->
parent != NULL) {
907 for (GList *gIter = bundle_data->replicas; gIter != NULL;
908 gIter = gIter->next) {
911 if (replica->
remote == remote) {
923 GHashTable *params = NULL;
939 xmlNode *xml,
const char *field)
950 replica = replica_for_remote(rsc);
951 if (replica == NULL) {
960 node = pe__current_node(replica->
container);
964 crm_trace(
"Cannot determine address for bundle connection %s", rsc->
id);
968 crm_trace(
"Setting address for bundle connection %s to bundle host %s",
969 rsc->
id, pe__node_name(node));
970 if(xml != NULL && field != NULL) {
977 #define pe__set_bundle_mount_flags(mount_xml, flags, flags_to_set) do { \ 978 flags = pcmk__set_flags_as(__func__, __LINE__, LOG_TRACE, \ 979 "Bundle mount", ID(mount_xml), flags, \ 980 (flags_to_set), #flags_to_set); \ 986 const char *value = NULL;
987 xmlNode *xml_obj = NULL;
988 xmlNode *xml_resource = NULL;
990 bool need_log_mount = TRUE;
997 bundle_data->prefix = strdup(rsc->
id);
1000 if (xml_obj != NULL) {
1004 if (xml_obj != NULL) {
1008 if (xml_obj != NULL) {
1018 if (value == NULL) {
1026 if ((value == NULL) && (bundle_data->promoted_max > 0)) {
1027 bundle_data->nreplicas = bundle_data->promoted_max;
1039 if (bundle_data->nreplicas_per_host == 1) {
1057 bundle_data->add_host = TRUE;
1060 for (xmlNode *xml_child = pcmk__xe_first_child(xml_obj); xml_child != NULL;
1061 xml_child = pcmk__xe_next(xml_child)) {
1063 pe__bundle_port_t *port = calloc(1,
sizeof(pe__bundle_port_t));
1066 if(port->source == NULL) {
1072 if(port->source != NULL && strlen(port->source) > 0) {
1073 if(port->target == NULL) {
1074 port->target = strdup(port->source);
1076 bundle_data->ports = g_list_append(bundle_data->ports, port);
1079 pe_err(
"Invalid port directive %s",
ID(xml_child));
1086 for (xmlNode *xml_child = pcmk__xe_first_child(xml_obj); xml_child != NULL;
1087 xml_child = pcmk__xe_next(xml_child)) {
1094 if (source == NULL) {
1101 mount_add(bundle_data, source,
target, options,
flags);
1102 if (strcmp(
target,
"/var/log") == 0) {
1103 need_log_mount = FALSE;
1106 pe_err(
"Invalid mount directive %s",
ID(xml_child));
1111 if (xml_obj && valid_network(bundle_data)) {
1113 xmlNode *xml_set = NULL;
1122 (bundle_data->promoted_max?
"master" 1123 : (
const char *)xml_resource->name));
1126 crm_xml_set_id(xml_set,
"%s-%s-meta", bundle_data->prefix, xml_resource->name);
1131 value = pcmk__itoa(bundle_data->nreplicas);
1135 value = pcmk__itoa(bundle_data->nreplicas_per_host);
1140 pcmk__btoa(bundle_data->nreplicas_per_host > 1));
1142 if (bundle_data->promoted_max) {
1146 value = pcmk__itoa(bundle_data->promoted_max);
1154 }
else if(xml_obj) {
1155 pe_err(
"Cannot control %s inside %s without either ip-range-start or control-port",
1156 rsc->
id,
ID(xml_obj));
1162 GList *childIter = NULL;
1163 pe__bundle_port_t *port = NULL;
1164 GString *buffer = NULL;
1195 if (need_log_mount) {
1200 port = calloc(1,
sizeof(pe__bundle_port_t));
1201 if(bundle_data->control_port) {
1202 port->source = strdup(bundle_data->control_port);
1214 port->target = strdup(port->source);
1215 bundle_data->ports = g_list_append(bundle_data->ports, port);
1217 buffer = g_string_sized_new(1024);
1218 for (childIter = bundle_data->child->children; childIter != NULL;
1219 childIter = childIter->next) {
1223 replica->
child = childIter->data;
1232 allocate_ip(bundle_data, replica, buffer);
1233 bundle_data->replicas = g_list_append(bundle_data->replicas,
1235 bundle_data->attribute_target = g_hash_table_lookup(replica->
child->
meta,
1238 bundle_data->container_host_options = g_string_free(buffer, FALSE);
1240 if (bundle_data->attribute_target) {
1242 strdup(bundle_data->attribute_target));
1243 g_hash_table_replace(bundle_data->child->meta,
1245 strdup(bundle_data->attribute_target));
1250 GString *buffer = g_string_sized_new(1024);
1252 for (
int lpc = 0; lpc < bundle_data->nreplicas; lpc++) {
1256 allocate_ip(bundle_data, replica, buffer);
1257 bundle_data->replicas = g_list_append(bundle_data->replicas,
1260 bundle_data->container_host_options = g_string_free(buffer, FALSE);
1263 for (GList *gIter = bundle_data->replicas; gIter != NULL;
1264 gIter = gIter->next) {
1267 if (create_replica_resources(rsc, bundle_data, replica) !=
pcmk_rc_ok) {
1268 pe_err(
"Failed unpacking resource %s", rsc->
id);
1289 if (replica->
child != NULL) {
1297 if (bundle_data->child) {
1307 gboolean child_active = rsc->
fns->
active(rsc, all);
1309 if (child_active && !all) {
1311 }
else if (!child_active && all) {
1325 for (iter = bundle_data->replicas; iter != NULL; iter = iter->next) {
1329 rsc_active = replica_resource_active(replica->
ip, all);
1330 if (rsc_active >= 0) {
1331 return (gboolean) rsc_active;
1334 rsc_active = replica_resource_active(replica->
child, all);
1335 if (rsc_active >= 0) {
1336 return (gboolean) rsc_active;
1339 rsc_active = replica_resource_active(replica->
container, all);
1340 if (rsc_active >= 0) {
1341 return (gboolean) rsc_active;
1344 rsc_active = replica_resource_active(replica->
remote, all);
1345 if (rsc_active >= 0) {
1346 return (gboolean) rsc_active;
1373 for (GList *gIter = bundle_data->replicas; gIter != NULL;
1374 gIter = gIter->next) {
1379 return replica->
child;
1390 print_rsc_in_list(
pcmk_resource_t *rsc,
const char *pre_text,
long options,
1397 rsc->
fns->
print(rsc, pre_text, options, print_data);
1409 bundle_print_xml(
pcmk_resource_t *rsc,
const char *pre_text,
long options,
1413 char *child_text = NULL;
1416 if (pre_text == NULL) {
1425 status_print(
"type=\"%s\" ", container_agent_str(bundle_data->agent_type));
1433 for (GList *gIter = bundle_data->replicas; gIter != NULL;
1434 gIter = gIter->next) {
1439 pre_text, replica->
offset);
1440 print_rsc_in_list(replica->
ip, child_text, options, print_data);
1441 print_rsc_in_list(replica->
child, child_text, options, print_data);
1442 print_rsc_in_list(replica->
container, child_text, options, print_data);
1443 print_rsc_in_list(replica->
remote, child_text, options, print_data);
1455 uint32_t show_opts = va_arg(args, uint32_t);
1457 GList *only_node = va_arg(args, GList *);
1458 GList *only_rsc = va_arg(args, GList *);
1462 gboolean printed_header = FALSE;
1463 gboolean print_everything = TRUE;
1465 const char *desc = NULL;
1477 for (GList *gIter = bundle_data->replicas; gIter != NULL;
1478 gIter = gIter->next) {
1481 gboolean print_ip, print_child, print_ctnr, print_remote;
1489 print_ip = replica->
ip != NULL &&
1491 print_child = replica->
child != NULL &&
1494 print_remote = replica->
remote != NULL &&
1497 if (!print_everything && !print_ip && !print_child && !print_ctnr && !print_remote) {
1501 if (!printed_header) {
1502 printed_header = TRUE;
1508 "type", container_agent_str(bundle_data->agent_type),
1509 "image", bundle_data->image,
1515 "description", desc);
1519 id = pcmk__itoa(replica->
offset);
1525 out->message(out, crm_map_element_name(replica->
ip->
xml), show_opts,
1526 replica->
ip, only_node, only_rsc);
1530 out->message(out, crm_map_element_name(replica->
child->
xml), show_opts,
1531 replica->
child, only_node, only_rsc);
1535 out->message(out, crm_map_element_name(replica->
container->
xml), show_opts,
1536 replica->
container, only_node, only_rsc);
1540 out->message(out, crm_map_element_name(replica->
remote->
xml), show_opts,
1541 replica->
remote, only_node, only_rsc);
1547 if (printed_header) {
1561 char buffer[LINE_MAX];
1568 offset += snprintf(buffer + offset, LINE_MAX - offset,
"%s",
1571 offset += snprintf(buffer + offset, LINE_MAX - offset,
"%s",
1575 offset += snprintf(buffer + offset, LINE_MAX - offset,
" (%s)",
1595 return " (maintenance)";
1598 return " (unmanaged)";
1608 uint32_t show_opts = va_arg(args, uint32_t);
1610 GList *only_node = va_arg(args, GList *);
1611 GList *only_rsc = va_arg(args, GList *);
1613 const char *desc = NULL;
1616 gboolean print_everything = TRUE;
1630 for (GList *gIter = bundle_data->replicas; gIter != NULL;
1631 gIter = gIter->next) {
1633 gboolean print_ip, print_child, print_ctnr, print_remote;
1641 print_ip = replica->
ip != NULL &&
1643 print_child = replica->
child != NULL &&
1646 print_remote = replica->
remote != NULL &&
1650 (print_everything == FALSE && (print_ip || print_child || print_ctnr || print_remote))) {
1657 (bundle_data->nreplicas > 1)?
" set" :
"",
1658 rsc->
id, bundle_data->image,
1660 desc ?
" (" :
"", desc ? desc :
"", desc ?
")" :
"",
1661 get_unmanaged_str(rsc));
1663 if (pcmk__list_of_multiple(bundle_data->replicas)) {
1664 out->begin_list(out, NULL, NULL,
"Replica[%d]", replica->
offset);
1668 out->message(out, crm_map_element_name(replica->
ip->
xml),
1669 new_show_opts, replica->
ip, only_node, only_rsc);
1673 out->message(out, crm_map_element_name(replica->
child->
xml),
1674 new_show_opts, replica->
child, only_node, only_rsc);
1678 out->message(out, crm_map_element_name(replica->
container->
xml),
1679 new_show_opts, replica->
container, only_node, only_rsc);
1683 out->message(out, crm_map_element_name(replica->
remote->
xml),
1684 new_show_opts, replica->
remote, only_node, only_rsc);
1687 if (pcmk__list_of_multiple(bundle_data->replicas)) {
1690 }
else if (print_everything == FALSE && !(print_ip || print_child || print_ctnr || print_remote)) {
1694 (bundle_data->nreplicas > 1)?
" set" :
"",
1695 rsc->
id, bundle_data->image,
1697 desc ?
" (" :
"", desc ? desc :
"", desc ?
")" :
"",
1698 get_unmanaged_str(rsc));
1700 pe__bundle_replica_output_html(out, replica, pe__current_node(replica->
container),
1716 char buffer[LINE_MAX];
1723 offset += snprintf(buffer + offset, LINE_MAX - offset,
"%s",
1726 offset += snprintf(buffer + offset, LINE_MAX - offset,
"%s",
1730 offset += snprintf(buffer + offset, LINE_MAX - offset,
" (%s)",
1742 uint32_t show_opts = va_arg(args, uint32_t);
1744 GList *only_node = va_arg(args, GList *);
1745 GList *only_rsc = va_arg(args, GList *);
1747 const char *desc = NULL;
1750 gboolean print_everything = TRUE;
1764 for (GList *gIter = bundle_data->replicas; gIter != NULL;
1765 gIter = gIter->next) {
1767 gboolean print_ip, print_child, print_ctnr, print_remote;
1775 print_ip = replica->
ip != NULL &&
1777 print_child = replica->
child != NULL &&
1780 print_remote = replica->
remote != NULL &&
1784 (print_everything == FALSE && (print_ip || print_child || print_ctnr || print_remote))) {
1791 (bundle_data->nreplicas > 1)?
" set" :
"",
1792 rsc->
id, bundle_data->image,
1794 desc ?
" (" :
"", desc ? desc :
"", desc ?
")" :
"",
1795 get_unmanaged_str(rsc));
1797 if (pcmk__list_of_multiple(bundle_data->replicas)) {
1798 out->list_item(out, NULL,
"Replica[%d]", replica->
offset);
1801 out->begin_list(out, NULL, NULL, NULL);
1804 out->message(out, crm_map_element_name(replica->
ip->
xml),
1805 new_show_opts, replica->
ip, only_node, only_rsc);
1809 out->message(out, crm_map_element_name(replica->
child->
xml),
1810 new_show_opts, replica->
child, only_node, only_rsc);
1814 out->message(out, crm_map_element_name(replica->
container->
xml),
1815 new_show_opts, replica->
container, only_node, only_rsc);
1819 out->message(out, crm_map_element_name(replica->
remote->
xml),
1820 new_show_opts, replica->
remote, only_node, only_rsc);
1824 }
else if (print_everything == FALSE && !(print_ip || print_child || print_ctnr || print_remote)) {
1828 (bundle_data->nreplicas > 1)?
" set" :
"",
1829 rsc->
id, bundle_data->image,
1831 desc ?
" (" :
"", desc ? desc :
"", desc ?
")" :
"",
1832 get_unmanaged_str(rsc));
1834 pe__bundle_replica_output_text(out, replica, pe__current_node(replica->
container),
1849 long options,
void *print_data)
1855 char buffer[LINE_MAX];
1862 offset += snprintf(buffer + offset, LINE_MAX - offset,
"%s",
1865 offset += snprintf(buffer + offset, LINE_MAX - offset,
"%s",
1869 offset += snprintf(buffer + offset, LINE_MAX - offset,
" (%s)",
1873 node = pe__current_node(replica->
container);
1874 common_print(rsc, pre_text, buffer, node, options, print_data);
1886 char *child_text = NULL;
1890 bundle_print_xml(rsc, pre_text, options, print_data);
1896 if (pre_text == NULL) {
1901 pre_text, ((bundle_data->nreplicas > 1)?
" set" :
""),
1902 rsc->
id, bundle_data->image,
1910 for (GList *gIter = bundle_data->replicas; gIter != NULL;
1911 gIter = gIter->next) {
1921 if (pcmk__list_of_multiple(bundle_data->replicas)) {
1927 print_rsc_in_list(replica->
ip, child_text, options, print_data);
1928 print_rsc_in_list(replica->
container, child_text, options, print_data);
1929 print_rsc_in_list(replica->
remote, child_text, options, print_data);
1930 print_rsc_in_list(replica->
child, child_text, options, print_data);
1936 print_bundle_replica(replica, child_text, options, print_data);
1952 if (replica == NULL) {
1956 if (replica->
node) {
1957 free(replica->
node);
1958 replica->
node = NULL;
1963 replica->
ip->
xml = NULL;
1992 free(bundle_data->prefix);
1993 free(bundle_data->image);
1994 free(bundle_data->control_port);
1995 free(bundle_data->host_network);
1996 free(bundle_data->host_netmask);
1997 free(bundle_data->ip_range_start);
1998 free(bundle_data->container_network);
1999 free(bundle_data->launcher_options);
2000 free(bundle_data->container_command);
2001 g_free(bundle_data->container_host_options);
2003 g_list_free_full(bundle_data->replicas,
2004 (GDestroyNotify) free_bundle_replica);
2005 g_list_free_full(bundle_data->mounts, (GDestroyNotify)mount_free);
2006 g_list_free_full(bundle_data->ports, (GDestroyNotify)port_free);
2009 if(bundle_data->child) {
2011 bundle_data->child->xml = NULL;
2012 bundle_data->child->fns->free(bundle_data->child);
2021 return container_role;
2040 return bundle_data->nreplicas;
2050 for (GList *item = bundle_data->replicas; item != NULL; item = item->next) {
2056 if (replica->
child) {
2070 gboolean check_parent)
2072 gboolean passes = FALSE;
2080 for (GList *gIter = bundle_data->replicas; gIter != NULL; gIter = gIter->next) {
2115 GList *containers = NULL;
2119 for (GList *iter =
data->replicas; iter != NULL; iter = iter->next) {
2122 containers = g_list_append(containers, replica->
container);
2130 unsigned int *count_clean)
2135 GList *containers = NULL;
2137 GHashTable *nodes = NULL;
2140 if (count_all != NULL) {
2143 if (count_clean != NULL) {
2154 for (iter =
data->replicas; iter != NULL; iter = iter->next) {
2158 containers = g_list_append(containers, replica->
container);
2161 if (containers == NULL) {
2171 if (pcmk__list_of_1(containers)) {
2172 container = containers->data;
2173 node = container->
fns->
active_node(container, count_all, count_clean);
2174 g_list_free(containers);
2179 nodes = g_hash_table_new(NULL, NULL);
2180 for (iter = containers; iter != NULL; iter = iter->next) {
2181 container = iter->data;
2183 for (GList *node_iter = container->
running_on; node_iter != NULL;
2184 node_iter = node_iter->next) {
2185 node = node_iter->data;
2188 if (g_hash_table_insert(nodes, (gpointer) node->
details,
2198 g_list_free(containers);
2199 g_hash_table_destroy(nodes);
2217 CRM_ASSERT(bundle_data->nreplicas_per_host >= 0);
2218 return (
unsigned int) bundle_data->nreplicas_per_host;
const pcmk_resource_t * pe__const_top_resource(const pcmk_resource_t *rsc, bool include_bundle)
void pe__print_bundle(pcmk_resource_t *rsc, const char *pre_text, long options, void *print_data)
#define CRM_CHECK(expr, failure_action)
Whether resource has clone notifications enabled.
void pe__count_bundle(pcmk_resource_t *rsc)
pcmk_node_t * pe__copy_node(const pcmk_node_t *this_node)
bool pe__is_guest_or_remote_node(const pcmk_node_t *node)
pcmk_scheduler_t * cluster
Cluster that resource is part of.
GHashTable * attrs
Node attributes.
pcmk_resource_t * ip
IP address resource for ipaddr.
Control output from tools.
int pcmk__scan_min_int(const char *text, int *result, int minimum)
gboolean pe__bundle_active(pcmk_resource_t *rsc, gboolean all)
Whether resource is an implicit container resource for a bundle replica.
#define PE__CONTAINER_AGENT_DOCKER_S
GList * children
Resource's child resources, if any.
#define XML_BOOLEAN_FALSE
xmlNode * first_named_child(const xmlNode *parent, const char *name)
gboolean pe__unpack_bundle(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler)
xmlNode * xml
Resource configuration (possibly expanded from template)
gboolean exclusive_discover
Whether exclusive probing is enabled.
#define PCMK_ACTION_MONITOR
const char * pe__resource_description(const pcmk_resource_t *rsc, uint32_t show_opts)
GHashTable * meta
Resource's meta-attributes.
void common_print(pcmk_resource_t *rsc, const char *pre_text, const char *name, const pcmk_node_t *node, long options, void *print_data)
Whether resource, its node, or entire cluster is in maintenance mode.
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
#define PCMK__ENV_REMOTE_PORT
const pcmk_resource_t * pe__get_rsc_in_container(const pcmk_resource_t *instance)
void pcmk__add_separated_word(GString **list, size_t init_size, const char *word, const char *separator)
#define PCMK_RESOURCE_CLASS_OCF
pcmk_node_t * pe_create_node(const char *id, const char *uname, const char *type, const char *score, pcmk_scheduler_t *scheduler)
#define CRM_LOG_ASSERT(expr)
void pe__foreach_const_bundle_replica(const pcmk_resource_t *bundle, bool(*fn)(const pe__bundle_replica_t *, void *), void *user_data)
const char * rsc_printable_id(const pcmk_resource_t *rsc)
unsigned int pe__bundle_max_per_node(const pcmk_resource_t *rsc)
void(* print)(pcmk_resource_t *rsc, const char *pre_text, long options, void *print_data)
pcmk_resource_t * container
Resource containing this one, if any.
Always probe resource on node.
Implementation of pcmk_scheduler_t.
#define XML_RSC_ATTR_TARGET
int pe__unpack_resource(xmlNode *xml_obj, pcmk_resource_t **rsc, pcmk_resource_t *parent, pcmk_scheduler_t *scheduler)
pcmk_resource_t * remote
Pacemaker Remote connection into container.
#define XML_RSC_ATTR_REMOTE_RA_ADDR
const char * pe__add_bundle_remote_name(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler, xmlNode *xml, const char *field)
int pe__bundle_html(pcmk__output_t *out, va_list args)
void crm_xml_sanitize_id(char *id)
Sanitize a string so it is usable as an XML ID.
#define pe__set_resource_flags(resource, flags_to_set)
#define DEFAULT_REMOTE_PORT
#define DEFAULT_REMOTE_KEY_LOCATION
#define get_bundle_variant_data(data, rsc)
#define XML_TAG_ATTR_SETS
#define XML_RSC_ATTR_PROMOTABLE
struct pe__bundle_variant_data_s pe__bundle_variant_data_t
int pe__bundle_max(const pcmk_resource_t *rsc)
xmlNode * pe_create_remote_xml(xmlNode *parent, const char *uname, const char *container_id, const char *migrateable, const char *is_managed, const char *start_timeout, const char *server, const char *port)
int weight
Node score for a given resource.
pcmk_resource_t * parent
Resource's parent resource, if any.
pcmk_resource_t * pe_find_resource(GList *rsc_list, const char *id_rh)
void common_free(pcmk_resource_t *rsc)
void(* free)(pcmk_resource_t *rsc)
Free all memory used by a resource.
int offset
0-origin index of this instance in bundle
Implementation of pcmk_resource_t.
int pe__bundle_text(pcmk__output_t *out, va_list args)
pcmk_node_t * node
Node created for this instance.
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute.
#define PCMK_META_CLONE_MAX
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
#define XML_CIB_TAG_RESOURCE
bool pe__bundle_needs_remote_name(pcmk_resource_t *rsc)
int pe__name_and_nvpairs_xml(pcmk__output_t *out, bool is_list, const char *tag_name, size_t pairs_count,...)
Whether resource is considered failed.
#define crm_trace(fmt, args...)
PCMK__OUTPUT_ARGS("bundle", "uint32_t", "pcmk_resource_t *", "GList *", "GList *")
#define PE__CONTAINER_AGENT_PODMAN_S
void pcmk__g_strcat(GString *buffer,...) G_GNUC_NULL_TERMINATED
bool xml_contains_remote_node(xmlNode *xml)
pcmk_node_t * pe_find_node(const GList *node_list, const char *node_name)
Find a node by name in a list of nodes.
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
xmlNode * add_node_copy(xmlNode *new_parent, xmlNode *xml_node)
void crm_xml_set_id(xmlNode *xml, const char *format,...) G_GNUC_PRINTF(2
struct pe_node_shared_s * details
Basic node information.
#define pe__set_bundle_mount_flags(mount_xml, flags, flags_to_set)
#define XML_AGENT_ATTR_PROVIDER
pcmk_resource_t * pe__first_container(const pcmk_resource_t *bundle)
unsigned long long flags
Group of enum pcmk_rsc_flags.
const char * uname
Node name in cluster.
#define XML_RSC_ATTR_ORDERED
#define XML_TAG_META_SETS
void pcmk__str_update(char **str, const char *value)
pcmk_resource_t * container
Container associated with this instance.
xmlNode * create_xml_node(xmlNode *parent, const char *name)
char * ipaddr
IP address associated with this instance.
Never probe resource on node.
GHashTable * utilization
Resource's utilization attributes.
void pe__foreach_bundle_replica(pcmk_resource_t *bundle, bool(*fn)(pe__bundle_replica_t *, void *), void *user_data)
#define PCMK_META_PROMOTED_MAX
enum rsc_role_e pe__bundle_resource_state(const pcmk_resource_t *rsc, gboolean current)
void free_xml(xmlNode *child)
Implementation of pcmk_node_t.
enum pe_obj_types variant
Resource variant.
void pcmk__output_xml_pop_parent(pcmk__output_t *out)
GList * pe__bundle_containers(const pcmk_resource_t *bundle)
int rsc_discover_mode
Probe mode (enum pe_discover_e)
bool pe__node_is_bundle_instance(const pcmk_resource_t *bundle, const pcmk_node_t *node)
const char * id
Node ID at the cluster layer.
#define XML_RSC_ATTR_UNIQUE
#define PE__CONTAINER_AGENT_UNKNOWN_S
#define PCMK__OUTPUT_LIST_FOOTER(out_obj, retcode)
int crm_str_to_boolean(const char *s, int *ret)
gboolean(* active)(pcmk_resource_t *rsc, gboolean all)
Check whether a resource is active.
Whether resource is a remote connection allowed to run on a remote node.
int pe__bundle_xml(pcmk__output_t *out, va_list args)
#define PE__CONTAINER_AGENT_RKT_S
#define PCMK__OUTPUT_LIST_HEADER(out_obj, cond, retcode, title...)
int pe__common_output_html(pcmk__output_t *out, const pcmk_resource_t *rsc, const char *name, const pcmk_node_t *node, unsigned int options)
Cluster status and scheduling.
#define XML_CIB_TAG_INCARNATION
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
void add_hash_param(GHashTable *hash, const char *name, const char *value)
pcmk_rsc_methods_t * fns
Resource object methods.
void * variant_opaque
Variant-specific (and private) data.
pcmk_scheduler_t * scheduler
int pe__common_output_text(pcmk__output_t *out, const pcmk_resource_t *rsc, const char *name, const pcmk_node_t *node, unsigned int options)
pcmk_resource_t * pe__find_bundle_replica(const pcmk_resource_t *bundle, const pcmk_node_t *node)
#define status_print(fmt, args...)
void pe__free_bundle(pcmk_resource_t *rsc)
bool pcmk__rsc_filtered_by_node(pcmk_resource_t *rsc, GList *only_node)
This structure contains everything that makes up a single output formatter.
pcmk_node_t *(* active_node)(const pcmk_resource_t *rsc, unsigned int *count_all, unsigned int *count_clean)
Find a node (and optionally count all) where resource is active.
pcmk_node_t * allocated_to
Node resource is assigned to.
pcmk_resource_t * child
Instance of bundled resource.
#define pe__clear_resource_flags(resource, flags_to_clear)
gboolean(* is_filtered)(const pcmk_resource_t *rsc, GList *only_rsc, gboolean check_parent)
Check whether a given resource is in a list of resources.
GList * running_on
Nodes where resource may be active.
gboolean pe__bundle_is_filtered(const pcmk_resource_t *rsc, GList *only_rsc, gboolean check_parent)
A single instance of a bundle.
#define PCMK_META_CLONE_NODE_MAX
xmlNode * crm_create_op_xml(xmlNode *parent, const char *prefix, const char *task, const char *interval_spec, const char *timeout)
Create a CIB XML element for an operation.
bool pe__count_active_node(const pcmk_resource_t *rsc, pcmk_node_t *node, pcmk_node_t **active, unsigned int *count_all, unsigned int *count_clean)
Resource role is unknown.
int pe_bundle_replicas(const pcmk_resource_t *rsc)
Get the number of configured replicas in a bundle.
pcmk_node_t * pe__bundle_active_node(const pcmk_resource_t *rsc, unsigned int *count_all, unsigned int *count_clean)
#define pe_rsc_trace(rsc, fmt, args...)
xmlNode * crm_create_nvpair_xml(xmlNode *parent, const char *id, const char *name, const char *value)
Create an XML name/value pair.
GHashTable * pe_rsc_params(pcmk_resource_t *rsc, const pcmk_node_t *node, pcmk_scheduler_t *scheduler)
Get a table of resource parameters.
Whether resource is managed.
Whether resource is not an anonymous clone instance.
void(* count)(pcmk_resource_t *rsc)
Increment cluster's instance counts for a resource.
pcmk_resource_t * remote_rsc
Remote connection resource for node, if it is a Pacemaker Remote node.
#define XML_AGENT_ATTR_CLASS
pcmk_resource_t * pe__bundled_resource(const pcmk_resource_t *rsc)
char * id
Resource ID in configuration.
GHashTable * allowed_nodes
Nodes where resource may run (key is node ID, not name)
gboolean pcmk__str_in_list(const gchar *s, const GList *lst, uint32_t flags)