18 #define VARIANT_CONTAINER 1 24 next_ip(
const char *last_ip)
26 unsigned int oct1 = 0;
27 unsigned int oct2 = 0;
28 unsigned int oct3 = 0;
29 unsigned int oct4 = 0;
30 int rc = sscanf(last_ip,
"%u.%u.%u.%u", &oct1, &oct2, &oct3, &oct4);
36 }
else if (oct3 > 253) {
39 }
else if (oct4 > 253) {
51 allocate_ip(container_variant_data_t *
data, container_grouping_t *tuple,
char *buffer,
int max)
53 if(data->ip_range_start == NULL) {
56 }
else if(data->ip_last) {
57 tuple->ipaddr = next_ip(data->ip_last);
60 tuple->ipaddr = strdup(data->ip_range_start);
63 data->ip_last = tuple->ipaddr;
65 return snprintf(buffer, max,
" --add-host=%s-%d:%s --link %s-docker-%d:%s-link-%d",
66 data->prefix, tuple->offset, tuple->ipaddr,
67 data->prefix, tuple->offset, data->prefix, tuple->offset);
69 if (data->type == PE_CONTAINER_TYPE_DOCKER || data->type == PE_CONTAINER_TYPE_PODMAN) {
70 if (data->add_host == FALSE) {
73 return snprintf(buffer, max,
" --add-host=%s-%d:%s",
74 data->prefix, tuple->offset, tuple->ipaddr);
75 }
else if (data->type == PE_CONTAINER_TYPE_RKT) {
76 return snprintf(buffer, max,
" --hosts-entry=%s=%s-%d",
77 tuple->ipaddr, data->prefix, tuple->offset);
85 create_resource(
const char *name,
const char *provider,
const char *kind)
110 valid_network(container_variant_data_t *data)
112 if(data->ip_range_start) {
115 if(data->control_port) {
116 if(data->replicas_per_host > 1) {
117 pe_err(
"Specifying the 'control-port' for %s requires 'replicas-per-host=1'", data->prefix);
118 data->replicas_per_host = 1;
128 resource_t *parent, container_variant_data_t *data, container_grouping_t *tuple,
131 if(data->ip_range_start) {
133 xmlNode *xml_ip = NULL;
134 xmlNode *xml_obj = NULL;
138 xml_ip = create_resource(
id,
"heartbeat",
"IPaddr2");
142 crm_xml_set_id(xml_obj,
"%s-attributes-%d", data->prefix, tuple->offset);
145 if(data->host_network) {
149 if(data->host_netmask) {
151 "cidr_netmask", data->host_netmask);
162 if (
common_unpack(xml_ip, &tuple->ip, parent, data_set) ==
false) {
172 create_docker_resource(
173 resource_t *parent, container_variant_data_t *data, container_grouping_t *tuple,
176 int offset = 0, max = 4096;
177 char *buffer = calloc(1, max+1);
179 int doffset = 0, dmax = 1024;
180 char *dbuffer = calloc(1, dmax+1);
183 xmlNode *xml_docker = NULL;
184 xmlNode *xml_obj = NULL;
188 xml_docker = create_resource(
id,
"heartbeat",
"docker");
192 crm_xml_set_id(xml_obj,
"%s-attributes-%d", data->prefix, tuple->offset);
199 offset += snprintf(buffer+offset, max-offset,
" --restart=no");
206 if (data->ip_range_start != NULL) {
207 offset += snprintf(buffer+offset, max-offset,
" -h %s-%d",
208 data->prefix, tuple->offset);
211 offset += snprintf(buffer+offset, max-offset,
" -e PCMK_stderr=1");
213 if(data->docker_network) {
215 offset += snprintf(buffer+offset, max-offset,
" --net=%s", data->docker_network);
218 if(data->control_port) {
219 offset += snprintf(buffer+offset, max-offset,
" -e PCMK_remote_port=%s", data->control_port);
221 offset += snprintf(buffer+offset, max-offset,
" -e PCMK_remote_port=%d",
DEFAULT_REMOTE_PORT);
224 for(
GListPtr pIter = data->mounts; pIter != NULL; pIter = pIter->next) {
225 container_mount_t *mount = pIter->data;
229 "%s/%s-%d", mount->source, data->prefix, tuple->offset);
232 doffset += snprintf(dbuffer+doffset, dmax-doffset,
",");
234 doffset += snprintf(dbuffer+doffset, dmax-doffset,
"%s", source);
235 offset += snprintf(buffer+offset, max-offset,
" -v %s:%s", source, mount->target);
239 offset += snprintf(buffer+offset, max-offset,
" -v %s:%s", mount->source, mount->target);
242 offset += snprintf(buffer+offset, max-offset,
":%s", mount->options);
246 for(
GListPtr pIter = data->ports; pIter != NULL; pIter = pIter->next) {
247 container_port_t *port = pIter->data;
250 offset += snprintf(buffer+offset, max-offset,
" -p %s:%s:%s",
251 tuple->ipaddr, port->source, port->target);
254 offset += snprintf(buffer+offset, max-offset,
" -p %s:%s", port->source, port->target);
258 if(data->docker_run_options) {
259 offset += snprintf(buffer+offset, max-offset,
" %s", data->docker_run_options);
262 if(data->docker_host_options) {
263 offset += snprintf(buffer+offset, max-offset,
" %s", data->docker_host_options);
273 if(data->docker_run_command) {
275 "run_cmd", data->docker_run_command);
278 "run_cmd",
SBIN_DIR "/pacemaker-remoted");
303 if(data->docker_run_command) {
305 "run_cmd", data->docker_run_command);
321 if (
common_unpack(xml_docker, &tuple->docker, parent, data_set) == FALSE) {
328 create_podman_resource(
resource_t *parent, container_variant_data_t *data, container_grouping_t *tuple,
331 int offset = 0, max = 4096;
332 char *buffer = calloc(1, max+1);
334 int doffset = 0, dmax = 1024;
335 char *dbuffer = calloc(1, dmax+1);
338 xmlNode *xml_podman = NULL;
339 xmlNode *xml_obj = NULL;
343 xml_podman = create_resource(
id,
"heartbeat",
"podman");
347 crm_xml_set_id(xml_obj,
"%s-attributes-%d", data->prefix, tuple->offset);
362 if (data->ip_range_start != NULL) {
363 offset += snprintf(buffer+offset, max-offset,
" -h %s-%d",
364 data->prefix, tuple->offset);
367 offset += snprintf(buffer+offset, max-offset,
" -e PCMK_stderr=1");
369 if(data->docker_network) {
372 offset += snprintf(buffer+offset, max-offset,
" --net=%s", data->docker_network);
375 if(data->control_port) {
376 offset += snprintf(buffer+offset, max-offset,
" -e PCMK_remote_port=%s", data->control_port);
378 offset += snprintf(buffer+offset, max-offset,
" -e PCMK_remote_port=%d",
DEFAULT_REMOTE_PORT);
381 for(
GListPtr pIter = data->mounts; pIter != NULL; pIter = pIter->next) {
382 container_mount_t *mount = pIter->data;
386 "%s/%s-%d", mount->source, data->prefix, tuple->offset);
389 doffset += snprintf(dbuffer+doffset, dmax-doffset,
",");
391 doffset += snprintf(dbuffer+doffset, dmax-doffset,
"%s", source);
392 offset += snprintf(buffer+offset, max-offset,
" -v %s:%s", source, mount->target);
396 offset += snprintf(buffer+offset, max-offset,
" -v %s:%s", mount->source, mount->target);
399 offset += snprintf(buffer+offset, max-offset,
":%s", mount->options);
403 for(
GListPtr pIter = data->ports; pIter != NULL; pIter = pIter->next) {
404 container_port_t *port = pIter->data;
407 offset += snprintf(buffer+offset, max-offset,
" -p %s:%s:%s",
408 tuple->ipaddr, port->source, port->target);
411 offset += snprintf(buffer+offset, max-offset,
" -p %s:%s", port->source, port->target);
415 if(data->docker_run_options) {
416 offset += snprintf(buffer+offset, max-offset,
" %s", data->docker_run_options);
419 if(data->docker_host_options) {
420 offset += snprintf(buffer+offset, max-offset,
" %s", data->docker_host_options);
430 if(data->docker_run_command) {
432 "run_cmd", data->docker_run_command);
435 "run_cmd",
SBIN_DIR "/pacemaker-remoted");
460 if(data->docker_run_command) {
462 "run_cmd", data->docker_run_command);
478 if (
common_unpack(xml_podman, &tuple->docker, parent, data_set) == FALSE) {
487 resource_t *parent, container_variant_data_t *data, container_grouping_t *tuple,
490 int offset = 0, max = 4096;
491 char *buffer = calloc(1, max+1);
493 int doffset = 0, dmax = 1024;
494 char *dbuffer = calloc(1, dmax+1);
497 xmlNode *xml_docker = NULL;
498 xmlNode *xml_obj = NULL;
504 xml_docker = create_resource(
id,
"heartbeat",
"rkt");
508 crm_xml_set_id(xml_obj,
"%s-attributes-%d", data->prefix, tuple->offset);
520 if (data->ip_range_start != NULL) {
521 offset += snprintf(buffer+offset, max-offset,
" --hostname=%s-%d",
522 data->prefix, tuple->offset);
525 offset += snprintf(buffer+offset, max-offset,
" --environment=PCMK_stderr=1");
527 if(data->docker_network) {
529 offset += snprintf(buffer+offset, max-offset,
" --net=%s", data->docker_network);
532 if(data->control_port) {
533 offset += snprintf(buffer+offset, max-offset,
" --environment=PCMK_remote_port=%s", data->control_port);
535 offset += snprintf(buffer+offset, max-offset,
" --environment=PCMK_remote_port=%d",
DEFAULT_REMOTE_PORT);
538 for(
GListPtr pIter = data->mounts; pIter != NULL; pIter = pIter->next) {
539 container_mount_t *mount = pIter->data;
543 "%s/%s-%d", mount->source, data->prefix, tuple->offset);
546 doffset += snprintf(dbuffer+doffset, dmax-doffset,
",");
548 doffset += snprintf(dbuffer+doffset, dmax-doffset,
"%s", source);
549 offset += snprintf(buffer+offset, max-offset,
" --volume vol%d,kind=host,source=%s", volid, source);
551 offset += snprintf(buffer+offset, max-offset,
",%s", mount->options);
553 offset += snprintf(buffer+offset, max-offset,
" --mount volume=vol%d,target=%s", volid, mount->target);
557 offset += snprintf(buffer+offset, max-offset,
" --volume vol%d,kind=host,source=%s", volid, mount->source);
559 offset += snprintf(buffer+offset, max-offset,
",%s", mount->options);
561 offset += snprintf(buffer+offset, max-offset,
" --mount volume=vol%d,target=%s", volid, mount->target);
566 for(
GListPtr pIter = data->ports; pIter != NULL; pIter = pIter->next) {
567 container_port_t *port = pIter->data;
570 offset += snprintf(buffer+offset, max-offset,
" --port=%s:%s:%s",
571 port->target, tuple->ipaddr, port->source);
573 offset += snprintf(buffer+offset, max-offset,
" --port=%s:%s", port->target, port->source);
577 if(data->docker_run_options) {
578 offset += snprintf(buffer+offset, max-offset,
" %s", data->docker_run_options);
581 if(data->docker_host_options) {
582 offset += snprintf(buffer+offset, max-offset,
" %s", data->docker_host_options);
592 if(data->docker_run_command) {
621 if(data->docker_run_command) {
623 data->docker_run_command);
640 if (
common_unpack(xml_docker, &tuple->docker, parent, data_set) == FALSE) {
656 gpointer match = g_hash_table_lookup(rsc->
allowed_nodes, uname);
665 for (child = rsc->
children; child != NULL; child = child->next) {
666 disallow_node((
resource_t *) (child->data), uname);
672 create_remote_resource(
673 resource_t *parent, container_variant_data_t *data, container_grouping_t *tuple,
676 if (tuple->child && valid_network(data)) {
677 GHashTableIter gIter;
680 xmlNode *xml_remote = NULL;
683 const char *uname = NULL;
684 const char *connect_name = NULL;
689 id =
crm_strdup_printf(
"pcmk-internal-%s-remote-%d", tuple->child->id, tuple->offset);
697 connect_name = (tuple->ipaddr? tuple->ipaddr :
"#uname");
699 if (data->control_port == NULL) {
710 connect_name, (data->control_port?
711 data->control_port : port_s));
720 uname =
ID(xml_remote);
752 for (rsc_iter = data_set->
resources; rsc_iter; rsc_iter = rsc_iter->next) {
753 disallow_node((
resource_t *) (rsc_iter->data), uname);
757 tuple->node->weight = 500;
761 if (tuple->child->allowed_nodes != NULL) {
762 g_hash_table_destroy(tuple->child->allowed_nodes);
764 tuple->child->allowed_nodes = g_hash_table_new_full(
crm_str_hash,
767 g_hash_table_insert(tuple->child->allowed_nodes, (gpointer) tuple->node->details->id,
node_copy(tuple->node));
772 g_hash_table_insert(tuple->child->parent->allowed_nodes, (gpointer) tuple->node->details->id, copy);
774 if (
common_unpack(xml_remote, &tuple->remote, parent, data_set) == FALSE) {
778 g_hash_table_iter_init(&gIter, tuple->remote->allowed_nodes);
779 while (g_hash_table_iter_next(&gIter, NULL, (
void **)&node)) {
786 tuple->node->details->remote_rsc = tuple->remote;
787 tuple->remote->container = tuple->docker;
792 g_hash_table_insert(tuple->node->details->attrs,
811 resource_t *parent, container_variant_data_t *data, container_grouping_t *tuple,
815 if (data->type == PE_CONTAINER_TYPE_DOCKER &&
816 create_docker_resource(parent, data, tuple, data_set) == FALSE) {
819 if (data->type == PE_CONTAINER_TYPE_PODMAN &&
820 create_podman_resource(parent, data, tuple, data_set) == FALSE) {
823 if (data->type == PE_CONTAINER_TYPE_RKT &&
824 create_rkt_resource(parent, data, tuple, data_set) == FALSE) {
828 if(create_ip_resource(parent, data, tuple, data_set) == FALSE) {
831 if(create_remote_resource(parent, data, tuple, data_set) == FALSE) {
834 if(tuple->child && tuple->ipaddr) {
855 mount_add(container_variant_data_t *container_data,
const char *source,
856 const char *target,
const char *options,
int flags)
858 container_mount_t *mount = calloc(1,
sizeof(container_mount_t));
860 mount->source = strdup(source);
861 mount->target = strdup(target);
863 mount->options = strdup(options);
865 mount->flags =
flags;
866 container_data->mounts = g_list_append(container_data->mounts, mount);
869 static void mount_free(container_mount_t *mount)
873 free(mount->options);
877 static void port_free(container_port_t *port)
884 static container_grouping_t *
888 container_variant_data_t *container_data = NULL;
894 while (top->
parent != NULL) {
898 get_container_variant_data(container_data, top);
899 for (
GListPtr gIter = container_data->tuples; gIter != NULL; gIter = gIter->next) {
900 container_grouping_t *tuple = (container_grouping_t *)gIter->data;
901 if(tuple->remote == remote) {
914 const char *attr_list[] = {
919 const char *value_list[] = {
930 value = g_hash_table_lookup(rsc->
parameters, name);
935 for (
int lpc = 0; lpc <
DIMOF(attr_list); lpc++) {
937 if (
safe_str_eq(value, value_list[lpc]) == FALSE) {
950 container_grouping_t *tuple = NULL;
956 tuple = tuple_for_remote(rsc);
961 node = tuple->docker->allocated_to;
966 node = pe__current_node(tuple->docker);
970 crm_trace(
"Cannot determine address for bundle connection %s", rsc->
id);
974 crm_trace(
"Setting address for bundle connection %s to bundle host %s",
976 if(xml != NULL && field != NULL) {
986 const char *value = NULL;
987 xmlNode *xml_obj = NULL;
988 xmlNode *xml_resource = NULL;
989 container_variant_data_t *container_data = NULL;
994 container_data = calloc(1,
sizeof(container_variant_data_t));
996 container_data->prefix = strdup(rsc->
id);
999 if (xml_obj != NULL) {
1000 container_data->type = PE_CONTAINER_TYPE_DOCKER;
1003 if (xml_obj != NULL) {
1004 container_data->type = PE_CONTAINER_TYPE_RKT;
1007 if (xml_obj != NULL) {
1008 container_data->type = PE_CONTAINER_TYPE_PODMAN;
1016 if (value == NULL) {
1021 if (container_data->promoted_max < 0) {
1022 pe_err(
"%s for %s must be nonnegative integer, using 0",
1024 container_data->promoted_max = 0;
1028 if ((value == NULL) && container_data->promoted_max) {
1029 container_data->replicas = container_data->promoted_max;
1033 if (container_data->replicas < 1) {
1034 pe_err(
"'replicas' for %s must be positive integer, using 1", rsc->
id);
1035 container_data->replicas = 1;
1044 container_data->replicas_per_host =
crm_parse_int(value,
"1");
1045 if (container_data->replicas_per_host < 1) {
1046 pe_err(
"'replicas-per-host' for %s must be positive integer, using 1",
1048 container_data->replicas_per_host = 1;
1050 if (container_data->replicas_per_host == 1) {
1068 container_data->add_host = TRUE;
1073 for (xmlNode *xml_child = __xml_first_child_element(xml_obj); xml_child != NULL;
1074 xml_child = __xml_next_element(xml_child)) {
1076 container_port_t *port = calloc(1,
sizeof(container_port_t));
1079 if(port->source == NULL) {
1085 if(port->source != NULL && strlen(port->source) > 0) {
1086 if(port->target == NULL) {
1087 port->target = strdup(port->source);
1089 container_data->ports = g_list_append(container_data->ports, port);
1092 pe_err(
"Invalid port directive %s",
ID(xml_child));
1099 for (xmlNode *xml_child = __xml_first_child_element(xml_obj); xml_child != NULL;
1100 xml_child = __xml_next_element(xml_child)) {
1107 if (source == NULL) {
1112 if (source && target) {
1113 mount_add(container_data, source, target, options, flags);
1115 pe_err(
"Invalid mount directive %s",
ID(xml_child));
1120 if (xml_obj && valid_network(container_data)) {
1122 xmlNode *xml_set = NULL;
1131 (container_data->promoted_max?
"master" 1132 : (
const char *)xml_resource->name));
1135 crm_xml_set_id(xml_set,
"%s-%s-meta", container_data->prefix, xml_resource->name);
1140 value = crm_itoa(container_data->replicas);
1145 value = crm_itoa(container_data->replicas_per_host);
1151 (container_data->replicas_per_host > 1)?
1154 if (container_data->promoted_max) {
1158 value = crm_itoa(container_data->promoted_max);
1167 }
else if(xml_obj) {
1168 pe_err(
"Cannot control %s inside %s without either ip-range-start or control-port",
1169 rsc->
id,
ID(xml_obj));
1177 container_port_t *port = NULL;
1179 int offset = 0, max = 1024;
1180 char *buffer = NULL;
1182 if (
common_unpack(xml_resource, &new_rsc, rsc, data_set) == FALSE) {
1183 pe_err(
"Failed unpacking resource %s",
ID(rsc->
xml));
1184 if (new_rsc != NULL && new_rsc->
fns != NULL) {
1190 container_data->child = new_rsc;
1218 port = calloc(1,
sizeof(container_port_t));
1219 if(container_data->control_port) {
1220 port->source = strdup(container_data->control_port);
1232 port->target = strdup(port->source);
1233 container_data->ports = g_list_append(container_data->ports, port);
1235 buffer = calloc(1, max+1);
1236 for(childIter = container_data->child->children; childIter != NULL; childIter = childIter->next) {
1237 container_grouping_t *tuple = calloc(1,
sizeof(container_grouping_t));
1238 tuple->child = childIter->data;
1239 tuple->child->exclusive_discover = TRUE;
1240 tuple->offset = lpc++;
1247 offset += allocate_ip(container_data, tuple, buffer+offset, max-offset);
1248 container_data->tuples = g_list_append(container_data->tuples, tuple);
1249 container_data->attribute_target = g_hash_table_lookup(tuple->child->meta,
XML_RSC_ATTR_TARGET);
1251 container_data->docker_host_options = buffer;
1252 if(container_data->attribute_target) {
1254 g_hash_table_replace(container_data->child->meta, strdup(
XML_RSC_ATTR_TARGET), strdup(container_data->attribute_target));
1259 int offset = 0, max = 1024;
1260 char *buffer = calloc(1, max+1);
1262 for(
int lpc = 0; lpc < container_data->replicas; lpc++) {
1263 container_grouping_t *tuple = calloc(1,
sizeof(container_grouping_t));
1264 tuple->offset = lpc;
1265 offset += allocate_ip(container_data, tuple, buffer+offset, max-offset);
1266 container_data->tuples = g_list_append(container_data->tuples, tuple);
1269 container_data->docker_host_options = buffer;
1272 for (
GListPtr gIter = container_data->tuples; gIter != NULL; gIter = gIter->next) {
1273 container_grouping_t *tuple = (container_grouping_t *)gIter->data;
1274 if (create_container(rsc, container_data, tuple, data_set) == FALSE) {
1275 pe_err(
"Failed unpacking resource %s", rsc->
id);
1281 if(container_data->child) {
1288 tuple_rsc_active(
resource_t *rsc, gboolean all)
1291 gboolean child_active = rsc->
fns->
active(rsc, all);
1293 if (child_active && !all) {
1295 }
else if (!child_active && all) {
1305 container_variant_data_t *container_data = NULL;
1308 get_container_variant_data(container_data, rsc);
1309 for (iter = container_data->tuples; iter != NULL; iter = iter->next) {
1310 container_grouping_t *tuple = (container_grouping_t *)(iter->data);
1313 rsc_active = tuple_rsc_active(tuple->ip, all);
1314 if (rsc_active >= 0) {
1315 return (gboolean) rsc_active;
1318 rsc_active = tuple_rsc_active(tuple->child, all);
1319 if (rsc_active >= 0) {
1320 return (gboolean) rsc_active;
1323 rsc_active = tuple_rsc_active(tuple->docker, all);
1324 if (rsc_active >= 0) {
1325 return (gboolean) rsc_active;
1328 rsc_active = tuple_rsc_active(tuple->remote, all);
1329 if (rsc_active >= 0) {
1330 return (gboolean) rsc_active;
1353 container_variant_data_t *container_data = NULL;
1356 get_container_variant_data(container_data, bundle);
1357 for (
GListPtr gIter = container_data->tuples; gIter != NULL;
1358 gIter = gIter->next) {
1359 container_grouping_t *tuple = (container_grouping_t *)gIter->data;
1362 if (tuple->node->details == node->
details) {
1363 return tuple->child;
1370 print_rsc_in_list(
resource_t *rsc,
const char *pre_text,
long options,
1377 rsc->
fns->
print(rsc, pre_text, options, print_data);
1378 if (options & pe_print_html) {
1385 container_type_as_string(
enum container_type t)
1387 if (t == PE_CONTAINER_TYPE_DOCKER) {
1388 return PE_CONTAINER_TYPE_DOCKER_S;
1389 }
else if (t == PE_CONTAINER_TYPE_RKT) {
1390 return PE_CONTAINER_TYPE_RKT_S;
1391 }
else if (t == PE_CONTAINER_TYPE_PODMAN) {
1392 return PE_CONTAINER_TYPE_PODMAN_S;
1394 return PE_CONTAINER_TYPE_UNKNOWN_S;
1399 container_print_xml(
resource_t * rsc,
const char *pre_text,
long options,
void *print_data)
1401 container_variant_data_t *container_data = NULL;
1402 char *child_text = NULL;
1405 if (pre_text == NULL) {
1408 child_text = crm_concat(pre_text,
" ",
' ');
1410 get_container_variant_data(container_data, rsc);
1417 for (
const char *c = container_type_as_string(container_data->type);
1429 for (
GListPtr gIter = container_data->tuples; gIter != NULL; gIter = gIter->next) {
1430 container_grouping_t *tuple = (container_grouping_t *)gIter->data;
1433 status_print(
"%s <replica id=\"%d\">\n", pre_text, tuple->offset);
1434 print_rsc_in_list(tuple->ip, child_text, options, print_data);
1435 print_rsc_in_list(tuple->child, child_text, options, print_data);
1436 print_rsc_in_list(tuple->docker, child_text, options, print_data);
1437 print_rsc_in_list(tuple->remote, child_text, options, print_data);
1445 tuple_print(container_grouping_t * tuple,
const char *pre_text,
long options,
void *print_data)
1451 char buffer[LINE_MAX];
1454 rsc = tuple->docker;
1458 offset += snprintf(buffer + offset, LINE_MAX - offset,
"%s",
rsc_printable_id(tuple->remote));
1460 offset += snprintf(buffer + offset, LINE_MAX - offset,
"%s",
rsc_printable_id(tuple->docker));
1463 offset += snprintf(buffer + offset, LINE_MAX - offset,
" (%s)", tuple->ipaddr);
1466 node = pe__current_node(tuple->docker);
1467 common_print(rsc, pre_text, buffer, node, options, print_data);
1473 container_variant_data_t *container_data = NULL;
1474 char *child_text = NULL;
1478 container_print_xml(rsc, pre_text, options, print_data);
1482 get_container_variant_data(container_data, rsc);
1484 if (pre_text == NULL) {
1489 pre_text, container_type_as_string(container_data->type),
1490 container_data->replicas>1?
" set":
"", rsc->
id, container_data->image,
1498 for (
GListPtr gIter = container_data->tuples; gIter != NULL; gIter = gIter->next) {
1499 container_grouping_t *tuple = (container_grouping_t *)gIter->data;
1502 if (options & pe_print_html) {
1508 if(g_list_length(container_data->tuples) > 1) {
1509 status_print(
" %sReplica[%d]\n", pre_text, tuple->offset);
1511 if (options & pe_print_html) {
1514 print_rsc_in_list(tuple->ip, child_text, options, print_data);
1515 print_rsc_in_list(tuple->docker, child_text, options, print_data);
1516 print_rsc_in_list(tuple->remote, child_text, options, print_data);
1517 print_rsc_in_list(tuple->child, child_text, options, print_data);
1518 if (options & pe_print_html) {
1523 tuple_print(tuple, child_text, options, print_data);
1527 if (options & pe_print_html) {
1531 if (options & pe_print_html) {
1550 tuple->ip->xml = NULL;
1551 tuple->ip->fns->free(tuple->ip);
1556 tuple->docker->xml = NULL;
1557 tuple->docker->fns->free(tuple->docker);
1558 tuple->docker = NULL;
1562 tuple->remote->xml = NULL;
1563 tuple->remote->fns->free(tuple->remote);
1564 tuple->remote = NULL;
1566 free(tuple->ipaddr);
1573 container_variant_data_t *container_data = NULL;
1576 get_container_variant_data(container_data, rsc);
1579 free(container_data->prefix);
1580 free(container_data->image);
1581 free(container_data->control_port);
1582 free(container_data->host_network);
1583 free(container_data->host_netmask);
1584 free(container_data->ip_range_start);
1585 free(container_data->docker_network);
1586 free(container_data->docker_run_options);
1587 free(container_data->docker_run_command);
1588 free(container_data->docker_host_options);
1590 g_list_free_full(container_data->tuples, (GDestroyNotify)
tuple_free);
1591 g_list_free_full(container_data->mounts, (GDestroyNotify)mount_free);
1592 g_list_free_full(container_data->ports, (GDestroyNotify)port_free);
1595 if(container_data->child) {
1596 free_xml(container_data->child->xml);
1597 container_data->child->xml = NULL;
1598 container_data->child->fns->free(container_data->child);
1607 return container_role;
1623 container_variant_data_t *container_data = NULL;
1625 get_container_variant_data(container_data, rsc);
1626 return container_data->replicas;
bool remote_id_conflict(const char *remote_name, pe_working_set_t *data)
#define CRM_CHECK(expr, failure_action)
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.
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)
#define XML_BOOLEAN_FALSE
xmlNode * first_named_child(const xmlNode *parent, const char *name)
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)
gboolean common_unpack(xmlNode *xml_obj, resource_t **rsc, resource_t *parent, pe_working_set_t *data_set)
void common_free(resource_t *rsc)
resource_object_functions_t * fns
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
#define status_print(fmt, args...)
int crm_parse_int(const char *text, const char *default_text)
Parse an integer value from a string.
#define CRM_LOG_ASSERT(expr)
pe_node_t * pe_find_node(GListPtr node_list, const char *uname)
#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
#define XML_RSC_ATTR_PROMOTABLE
gboolean is_remote_node(node_t *node)
#define set_bit(word, bit)
#define PCMK_RESOURCE_CLASS_OCF
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute.
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
#define XML_CIB_TAG_RESOURCE
resource_t * find_container_child(const resource_t *bundle, const node_t *node)
#define crm_trace(fmt, args...)
xmlNode * add_node_copy(xmlNode *new_parent, xmlNode *xml_node)
struct pe_node_shared_s * details
#define XML_AGENT_ATTR_PROVIDER
#define XML_RSC_ATTR_ORDERED
#define XML_TAG_META_SETS
xmlNode * create_xml_node(xmlNode *parent, const char *name)
void(* print)(pe_resource_t *, const char *, long, void *)
#define XML_RSC_ATTR_INCARNATION_NODEMAX
void(* free)(pe_resource_t *)
gboolean check_boolean(const char *value)
void free_xml(xmlNode *child)
enum pe_obj_types variant
bool container_fix_remote_addr(resource_t *rsc)
#define XML_RSC_ATTR_UNIQUE
void common_print(resource_t *rsc, const char *pre_text, const char *name, node_t *node, long options, void *print_data)
int crm_str_to_boolean(const char *s, int *ret)
#define XML_RSC_ATTR_PROMOTED_MAX
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)
Cluster status and scheduling.
void tuple_free(container_grouping_t *tuple)
#define XML_CIB_TAG_INCARNATION
void add_hash_param(GHashTable *hash, const char *name, const char *value)
const char * rsc_printable_id(pe_resource_t *rsc)
void crm_xml_set_id(xmlNode *xml, const char *format,...) __attribute__((__format__(__printf__
gboolean container_active(resource_t *rsc, gboolean all)
#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.
#define safe_str_eq(a, b)
const char * container_fix_remote_addr_in(resource_t *rsc, xmlNode *xml, const char *field)
void container_print(resource_t *rsc, const char *pre_text, long options, void *print_data)
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
gboolean(* active)(pe_resource_t *, gboolean)
#define XML_AGENT_ATTR_CLASS
GHashTable * allowed_nodes
void container_free(resource_t *rsc)