|
|
60de42 |
From 12e12aef412d5a06696a58292088dfe1d01b2e34 Mon Sep 17 00:00:00 2001
|
|
|
60de42 |
From: Andrew Beekhof <andrew@beekhof.net>
|
|
|
60de42 |
Date: Mon, 27 Mar 2017 18:56:43 +1100
|
|
|
60de42 |
Subject: [PATCH 1/3] PE: Containers: Allow custom control ports when using the
|
|
|
60de42 |
machine's local address
|
|
|
60de42 |
|
|
|
60de42 |
---
|
|
|
60de42 |
lib/pengine/container.c | 4 ++--
|
|
|
60de42 |
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
60de42 |
|
|
|
60de42 |
diff --git a/lib/pengine/container.c b/lib/pengine/container.c
|
|
|
60de42 |
index 6f3a3b9..710f5dc 100644
|
|
|
60de42 |
--- a/lib/pengine/container.c
|
|
|
60de42 |
+++ b/lib/pengine/container.c
|
|
|
60de42 |
@@ -119,9 +119,9 @@ valid_network(container_variant_data_t *data)
|
|
|
60de42 |
if(data->ip_range_start) {
|
|
|
60de42 |
return TRUE;
|
|
|
60de42 |
}
|
|
|
60de42 |
- if(data->control_port && crm_str_eq(data->docker_network, "host", TRUE)) {
|
|
|
60de42 |
+ if(data->control_port) {
|
|
|
60de42 |
if(data->replicas_per_host > 1) {
|
|
|
60de42 |
- pe_err("Specifying the 'control-port' with 'internal-network=host' for %s requires 'replicas-per-host=1'", data->prefix);
|
|
|
60de42 |
+ pe_err("Specifying the 'control-port' for %s requires 'replicas-per-host=1'", data->prefix);
|
|
|
60de42 |
data->replicas_per_host = 1;
|
|
|
60de42 |
}
|
|
|
60de42 |
return TRUE;
|
|
|
60de42 |
--
|
|
|
60de42 |
1.8.3.1
|
|
|
60de42 |
|
|
|
60de42 |
|
|
|
60de42 |
From 2a6abd68c200d9c92e4003e26ff282619a4af346 Mon Sep 17 00:00:00 2001
|
|
|
60de42 |
From: Andrew Beekhof <andrew@beekhof.net>
|
|
|
60de42 |
Date: Tue, 28 Mar 2017 12:24:46 +1100
|
|
|
60de42 |
Subject: [PATCH 2/3] PE: Containers: Allow the internal and external ports to
|
|
|
60de42 |
optionally differ
|
|
|
60de42 |
|
|
|
60de42 |
---
|
|
|
60de42 |
lib/pengine/container.c | 39 +++++++++++++++++++++++++++++----------
|
|
|
60de42 |
lib/pengine/variant.h | 7 +++++++
|
|
|
60de42 |
xml/resources-2.8.rng | 7 ++++++-
|
|
|
60de42 |
3 files changed, 42 insertions(+), 11 deletions(-)
|
|
|
60de42 |
|
|
|
60de42 |
diff --git a/lib/pengine/container.c b/lib/pengine/container.c
|
|
|
60de42 |
index 710f5dc..ed63b80 100644
|
|
|
60de42 |
--- a/lib/pengine/container.c
|
|
|
60de42 |
+++ b/lib/pengine/container.c
|
|
|
60de42 |
@@ -232,13 +232,13 @@ create_docker_resource(
|
|
|
60de42 |
}
|
|
|
60de42 |
|
|
|
60de42 |
for(GListPtr pIter = data->ports; pIter != NULL; pIter = pIter->next) {
|
|
|
60de42 |
- char *port = pIter->data;
|
|
|
60de42 |
+ container_port_t *port = pIter->data;
|
|
|
60de42 |
|
|
|
60de42 |
if(tuple->ipaddr) {
|
|
|
60de42 |
offset += snprintf(buffer+offset, max-offset, " -p %s:%s:%s",
|
|
|
60de42 |
- tuple->ipaddr, port, port);
|
|
|
60de42 |
+ tuple->ipaddr, port->source, port->target);
|
|
|
60de42 |
} else {
|
|
|
60de42 |
- offset += snprintf(buffer+offset, max-offset, " -p %s:%s", port, port);
|
|
|
60de42 |
+ offset += snprintf(buffer+offset, max-offset, " -p %s:%s", port->source, port->target);
|
|
|
60de42 |
}
|
|
|
60de42 |
}
|
|
|
60de42 |
|
|
|
60de42 |
@@ -410,6 +410,13 @@ static void mount_free(container_mount_t *mount)
|
|
|
60de42 |
free(mount);
|
|
|
60de42 |
}
|
|
|
60de42 |
|
|
|
60de42 |
+static void port_free(container_port_t *port)
|
|
|
60de42 |
+{
|
|
|
60de42 |
+ free(port->source);
|
|
|
60de42 |
+ free(port->target);
|
|
|
60de42 |
+ free(port);
|
|
|
60de42 |
+}
|
|
|
60de42 |
+
|
|
|
60de42 |
gboolean
|
|
|
60de42 |
container_unpack(resource_t * rsc, pe_working_set_t * data_set)
|
|
|
60de42 |
{
|
|
|
60de42 |
@@ -465,16 +472,24 @@ container_unpack(resource_t * rsc, pe_working_set_t * data_set)
|
|
|
60de42 |
for (xmlNode *xml_child = __xml_first_child_element(xml_obj); xml_child != NULL;
|
|
|
60de42 |
xml_child = __xml_next_element(xml_child)) {
|
|
|
60de42 |
|
|
|
60de42 |
- char *port = crm_element_value_copy(xml_child, "port");
|
|
|
60de42 |
+ container_port_t *port = calloc(1, sizeof(container_port_t));
|
|
|
60de42 |
+ port->source = crm_element_value_copy(xml_child, "port");
|
|
|
60de42 |
|
|
|
60de42 |
- if(port == NULL) {
|
|
|
60de42 |
- port = crm_element_value_copy(xml_child, "range");
|
|
|
60de42 |
+ if(port->source == NULL) {
|
|
|
60de42 |
+ port->source = crm_element_value_copy(xml_child, "range");
|
|
|
60de42 |
+ } else {
|
|
|
60de42 |
+ port->target = crm_element_value_copy(xml_child, "internal-port");
|
|
|
60de42 |
}
|
|
|
60de42 |
|
|
|
60de42 |
- if(port != NULL) {
|
|
|
60de42 |
+ if(port->source != NULL && strlen(port->source) > 0) {
|
|
|
60de42 |
+ if(port->target == NULL) {
|
|
|
60de42 |
+ port->target = strdup(port->source);
|
|
|
60de42 |
+ }
|
|
|
60de42 |
container_data->ports = g_list_append(container_data->ports, port);
|
|
|
60de42 |
+
|
|
|
60de42 |
} else {
|
|
|
60de42 |
pe_err("Invalid port directive %s", ID(xml_child));
|
|
|
60de42 |
+ port_free(port);
|
|
|
60de42 |
}
|
|
|
60de42 |
}
|
|
|
60de42 |
}
|
|
|
60de42 |
@@ -557,6 +572,7 @@ container_unpack(resource_t * rsc, pe_working_set_t * data_set)
|
|
|
60de42 |
GListPtr childIter = NULL;
|
|
|
60de42 |
resource_t *new_rsc = NULL;
|
|
|
60de42 |
container_mount_t *mount = NULL;
|
|
|
60de42 |
+ container_port_t *port = calloc(1, sizeof(container_port_t));
|
|
|
60de42 |
|
|
|
60de42 |
int offset = 0, max = 1024;
|
|
|
60de42 |
char *buffer = calloc(1, max+1);
|
|
|
60de42 |
@@ -576,11 +592,14 @@ container_unpack(resource_t * rsc, pe_working_set_t * data_set)
|
|
|
60de42 |
container_data->mounts = g_list_append(container_data->mounts, mount);
|
|
|
60de42 |
|
|
|
60de42 |
if(container_data->control_port) {
|
|
|
60de42 |
- container_data->ports = g_list_append(container_data->ports, strdup(container_data->control_port));
|
|
|
60de42 |
+ port->source = strdup(container_data->control_port);
|
|
|
60de42 |
} else {
|
|
|
60de42 |
- container_data->ports = g_list_append(container_data->ports, crm_itoa(DEFAULT_REMOTE_PORT));
|
|
|
60de42 |
+ port->source = crm_itoa(DEFAULT_REMOTE_PORT);
|
|
|
60de42 |
}
|
|
|
60de42 |
|
|
|
60de42 |
+ port->target = strdup(port->source);
|
|
|
60de42 |
+ container_data->ports = g_list_append(container_data->ports, port);
|
|
|
60de42 |
+
|
|
|
60de42 |
if (common_unpack(xml_resource, &new_rsc, rsc, data_set) == FALSE) {
|
|
|
60de42 |
pe_err("Failed unpacking resource %s", crm_element_value(rsc->xml, XML_ATTR_ID));
|
|
|
60de42 |
if (new_rsc != NULL && new_rsc->fns != NULL) {
|
|
|
60de42 |
@@ -845,7 +864,7 @@ container_free(resource_t * rsc)
|
|
|
60de42 |
|
|
|
60de42 |
g_list_free_full(container_data->tuples, (GDestroyNotify)tuple_free);
|
|
|
60de42 |
g_list_free_full(container_data->mounts, (GDestroyNotify)mount_free);
|
|
|
60de42 |
- g_list_free_full(container_data->ports, free);
|
|
|
60de42 |
+ g_list_free_full(container_data->ports, (GDestroyNotify)port_free);
|
|
|
60de42 |
common_free(rsc);
|
|
|
60de42 |
}
|
|
|
60de42 |
|
|
|
60de42 |
diff --git a/lib/pengine/variant.h b/lib/pengine/variant.h
|
|
|
60de42 |
index 4a9e2fe..aa2a1b7 100644
|
|
|
60de42 |
--- a/lib/pengine/variant.h
|
|
|
60de42 |
+++ b/lib/pengine/variant.h
|
|
|
60de42 |
@@ -78,6 +78,13 @@ typedef struct
|
|
|
60de42 |
|
|
|
60de42 |
} container_mount_t;
|
|
|
60de42 |
|
|
|
60de42 |
+typedef struct
|
|
|
60de42 |
+{
|
|
|
60de42 |
+ char *source;
|
|
|
60de42 |
+ char *target;
|
|
|
60de42 |
+
|
|
|
60de42 |
+} container_port_t;
|
|
|
60de42 |
+
|
|
|
60de42 |
typedef struct container_variant_data_s {
|
|
|
60de42 |
int masters;
|
|
|
60de42 |
int replicas;
|
|
|
60de42 |
diff --git a/xml/resources-2.8.rng b/xml/resources-2.8.rng
|
|
|
60de42 |
index d10c666..870e804 100644
|
|
|
60de42 |
--- a/xml/resources-2.8.rng
|
|
|
60de42 |
+++ b/xml/resources-2.8.rng
|
|
|
60de42 |
@@ -115,7 +115,12 @@
|
|
|
60de42 |
<element name="port-mapping">
|
|
|
60de42 |
<attribute name="id"><data type="ID"/></attribute>
|
|
|
60de42 |
<choice>
|
|
|
60de42 |
- <attribute name="port"><data type="integer"/></attribute>
|
|
|
60de42 |
+ <group>
|
|
|
60de42 |
+ <attribute name="port"><data type="integer"/></attribute>
|
|
|
60de42 |
+ <optional>
|
|
|
60de42 |
+ <attribute name="internal-port"><data type="integer"/></attribute>
|
|
|
60de42 |
+ </optional>
|
|
|
60de42 |
+ </group>
|
|
|
60de42 |
<attribute name="range">
|
|
|
60de42 |
<data type="string">
|
|
|
60de42 |
<param name="pattern">([0-9\-]+)</param>
|
|
|
60de42 |
--
|
|
|
60de42 |
1.8.3.1
|
|
|
60de42 |
|
|
|
60de42 |
|
|
|
60de42 |
From ee9c3cea4efc4ff633ef4e6eb1b4a3d49c1695a5 Mon Sep 17 00:00:00 2001
|
|
|
60de42 |
From: Andrew Beekhof <andrew@beekhof.net>
|
|
|
60de42 |
Date: Tue, 28 Mar 2017 13:09:08 +1100
|
|
|
60de42 |
Subject: [PATCH 3/3] PE: Containers: Ensure replicas_per_host=1 is respected
|
|
|
60de42 |
during rediscovery and startup
|
|
|
60de42 |
|
|
|
60de42 |
---
|
|
|
60de42 |
pengine/container.c | 27 ++++++++++++++++++++++++++-
|
|
|
60de42 |
1 file changed, 26 insertions(+), 1 deletion(-)
|
|
|
60de42 |
|
|
|
60de42 |
diff --git a/pengine/container.c b/pengine/container.c
|
|
|
60de42 |
index b66b7b0..1623861 100644
|
|
|
60de42 |
--- a/pengine/container.c
|
|
|
60de42 |
+++ b/pengine/container.c
|
|
|
60de42 |
@@ -300,7 +300,32 @@ container_create_probe(resource_t * rsc, node_t * node, action_t * complete,
|
|
|
60de42 |
any_created |= tuple->child->cmds->create_probe(tuple->child, node, complete, force, data_set);
|
|
|
60de42 |
}
|
|
|
60de42 |
if(tuple->docker) {
|
|
|
60de42 |
- any_created |= tuple->docker->cmds->create_probe(tuple->docker, node, complete, force, data_set);
|
|
|
60de42 |
+ bool created = tuple->docker->cmds->create_probe(tuple->docker, node, complete, force, data_set);
|
|
|
60de42 |
+
|
|
|
60de42 |
+ if(created) {
|
|
|
60de42 |
+ any_created = TRUE;
|
|
|
60de42 |
+ /* If we're limited to one replica per host (due to
|
|
|
60de42 |
+ * the lack of an IP range probably), then we don't
|
|
|
60de42 |
+ * want any of our peer containers starting until
|
|
|
60de42 |
+ * we've established that no other copies are already
|
|
|
60de42 |
+ * running.
|
|
|
60de42 |
+ *
|
|
|
60de42 |
+ * Partly this is to ensure that replicas_per_host is
|
|
|
60de42 |
+ * observed, but also to ensure that the containers
|
|
|
60de42 |
+ * don't fail to start because the necessary port
|
|
|
60de42 |
+ * mappings (which wont include an IP for uniqueness)
|
|
|
60de42 |
+ * are already taken
|
|
|
60de42 |
+ */
|
|
|
60de42 |
+
|
|
|
60de42 |
+ for (GListPtr tIter = container_data->tuples; tIter != NULL && container_data->replicas_per_host == 1; tIter = tIter->next) {
|
|
|
60de42 |
+ container_grouping_t *other = (container_grouping_t *)tIter->data;
|
|
|
60de42 |
+ if(other != tuple) {
|
|
|
60de42 |
+ custom_action_order(tuple->docker, generate_op_key(tuple->docker->id, RSC_STATUS, 0), NULL,
|
|
|
60de42 |
+ other->docker, generate_op_key(other->docker->id, RSC_START, 0), NULL,
|
|
|
60de42 |
+ pe_order_optional, data_set);
|
|
|
60de42 |
+ }
|
|
|
60de42 |
+ }
|
|
|
60de42 |
+ }
|
|
|
60de42 |
}
|
|
|
60de42 |
if(FALSE && tuple->remote) {
|
|
|
60de42 |
// TODO: Needed?
|
|
|
60de42 |
--
|
|
|
60de42 |
1.8.3.1
|
|
|
60de42 |
|