From 585f0933810e13486bc99f9e32884e586aa50089 Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Tue, 26 Jan 2016 17:44:40 -0500 Subject: [PATCH 01/12] Start ICloudAPI change. --- flocker/node/agents/blockdevice.py | 9 ++++++--- flocker/node/agents/cinder.py | 7 +++++-- flocker/node/agents/ebs.py | 5 ++++- flocker/node/agents/test/test_blockdevice.py | 12 ++++++++++-- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/flocker/node/agents/blockdevice.py b/flocker/node/agents/blockdevice.py index 287486cd76..8eb33f268c 100644 --- a/flocker/node/agents/blockdevice.py +++ b/flocker/node/agents/blockdevice.py @@ -1121,8 +1121,10 @@ def list_live_nodes(): This is used to figure out which nodes are dead, so that other nodes can do the detach. - :returns: A collection of ``unicode`` compute instance IDs, compatible - with those returned by ``IBlockDeviceAPI.compute_instance_id``. + :returns: A mapping of ``unicode`` compute instance IDs + (compatible with those returned by + ``IBlockDeviceAPI.compute_instance_id``) to IPs of those + nodes, also as unicode.. """ def start_node(node_id): @@ -1647,7 +1649,8 @@ def is_existing_block_device(dataset_id, path): pass if ICloudAPI.providedBy(self._underlying_blockdevice_api): - live_instances = self._underlying_blockdevice_api.list_live_nodes() + live_instances = list( + self._underlying_blockdevice_api.list_live_nodes()) else: # Can't know accurately who is alive and who is dead: live_instances = None diff --git a/flocker/node/agents/cinder.py b/flocker/node/agents/cinder.py index 6b14b0b6c2..dac04d7f48 100644 --- a/flocker/node/agents/cinder.py +++ b/flocker/node/agents/cinder.py @@ -689,8 +689,11 @@ def get_device_path(self, blockdevice_id): # ICloudAPI: def list_live_nodes(self): - return list(server.id for server in self.nova_server_manager.list() - if server.status == u'ACTIVE') + return {server.id: + list(map( + unicode, _extract_nova_server_addresses(server.addresses))) + for server in self.nova_server_manager.list() + if server.status == u'ACTIVE'} def start_node(self, node_id): server = self.nova_server_manager.get(node_id) diff --git a/flocker/node/agents/ebs.py b/flocker/node/agents/ebs.py index 90259fa9eb..8ff888541c 100644 --- a/flocker/node/agents/ebs.py +++ b/flocker/node/agents/ebs.py @@ -1363,7 +1363,10 @@ def get_device_path(self, blockdevice_id): def list_live_nodes(self): instances = self.connection.instances.filter( Filters=[{'Name': 'instance-state-name', 'Values': ['running']}]) - return list(unicode(instance.id) for instance in instances) + return {unicode(instance.id): + [unicode(instance.public_ip_address), + unicode(instance.private_ip_address)] + for instance in instances} @boto3_log def start_node(self, node_id): diff --git a/flocker/node/agents/test/test_blockdevice.py b/flocker/node/agents/test/test_blockdevice.py index 5f5e995ea5..d83450554b 100644 --- a/flocker/node/agents/test/test_blockdevice.py +++ b/flocker/node/agents/test/test_blockdevice.py @@ -754,7 +754,9 @@ def __init__(self, block_api, live_nodes=()): self.live_nodes = live_nodes def list_live_nodes(self): - return [self.compute_instance_id()] + list(self.live_nodes) + return {node: [u"10.1.1.{}".format(i)] + for i, node in enumerate( + [self.compute_instance_id()] + list(self.live_nodes))} def start_node(self, node_id): return @@ -5501,11 +5503,17 @@ def test_current_machine_is_live(self): self.assertIn(self.api.compute_instance_id(), live)) return d + def test_current_machine_has_appropriate_ip(self): + """ + The machine's known IP is set for the current node. + """ + # XXX ... + def test_list_live_nodes(self): """ ``list_live_nodes`` returns an iterable of unicode values. """ - live_nodes = self.api.list_live_nodes() + live_nodes = list(self.api.list_live_nodes()) self.assertThat(live_nodes, AllMatch(IsInstance(unicode))) return Tests From dc5ba06374ebb2f505aa86767759b862fdae1eeb Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Wed, 27 Jan 2016 09:27:30 -0500 Subject: [PATCH 02/12] FakeCloudAPI updated, and test for listing appropriate IPs. --- flocker/node/agents/test/test_blockdevice.py | 21 +++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/flocker/node/agents/test/test_blockdevice.py b/flocker/node/agents/test/test_blockdevice.py index d83450554b..197f2857db 100644 --- a/flocker/node/agents/test/test_blockdevice.py +++ b/flocker/node/agents/test/test_blockdevice.py @@ -97,7 +97,7 @@ _backing_file_name, ) from ....common.algebraic import tagged_union_strategy - +from ....common import get_all_ips from ... import run_state_change, in_parallel, ILocalState, IStateChange, NoOp from ...testtools import ( @@ -754,9 +754,12 @@ def __init__(self, block_api, live_nodes=()): self.live_nodes = live_nodes def list_live_nodes(self): - return {node: [u"10.1.1.{}".format(i)] - for i, node in enumerate( - [self.compute_instance_id()] + list(self.live_nodes))} + result = {self.compute_instance_id(): + set(unicode(i) for i in get_all_ips() + if i != b"127.0.0.1")} + result.update({node: [u"10.1.1.{}".format(i)] + for i, node in enumerate(self.live_nodes)}) + return result def start_node(self, node_id): return @@ -5507,7 +5510,15 @@ def test_current_machine_has_appropriate_ip(self): """ The machine's known IP is set for the current node. """ - # XXX ... + local_addresses = set(unicode(i) for i in get_all_ips() + if i != b"127.0.0.1") + d = self.async_cloud_api.list_live_nodes() + d.addCallback( + lambda live: + self.assertTrue( + set(live[self.api.compute_instance_id()]).intersection( + local_addresses))) + return d def test_list_live_nodes(self): """ From e2437dd9bd000b1368758063e872f29a7d080717 Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Wed, 27 Jan 2016 09:44:57 -0500 Subject: [PATCH 03/12] Don't use env variable anymore to find public IPs for nodes. --- admin/acceptance.py | 5 -- flocker/acceptance/endtoend/test_installer.py | 1 - flocker/acceptance/testtools.py | 60 ++++++++++++++----- 3 files changed, 45 insertions(+), 21 deletions(-) diff --git a/admin/acceptance.py b/admin/acceptance.py index dbb737d7e8..a19831189b 100644 --- a/admin/acceptance.py +++ b/admin/acceptance.py @@ -94,11 +94,6 @@ def get_trial_environment(cluster): 'FLOCKER_ACCEPTANCE_VOLUME_BACKEND': cluster.dataset_backend.name, 'FLOCKER_ACCEPTANCE_API_CERTIFICATES_PATH': cluster.certificates_path.path, - 'FLOCKER_ACCEPTANCE_HOSTNAME_TO_PUBLIC_ADDRESS': json.dumps({ - node.private_address: node.address - for node in cluster.agent_nodes - if node.private_address is not None - }), 'FLOCKER_ACCEPTANCE_DEFAULT_VOLUME_SIZE': bytes( cluster.default_volume_size ), diff --git a/flocker/acceptance/endtoend/test_installer.py b/flocker/acceptance/endtoend/test_installer.py index 60f2bf38ea..92b49e4995 100644 --- a/flocker/acceptance/endtoend/test_installer.py +++ b/flocker/acceptance/endtoend/test_installer.py @@ -326,7 +326,6 @@ def _cleanup_flocker(self): control_node=self.control_node_ip.encode('ascii'), certificates_path=local_certs_path, num_agent_nodes=2, - hostname_to_public_address={}, username='user1', ) d.addCallback( diff --git a/flocker/acceptance/testtools.py b/flocker/acceptance/testtools.py index 85a4d56342..228dd5fe81 100644 --- a/flocker/acceptance/testtools.py +++ b/flocker/acceptance/testtools.py @@ -18,6 +18,8 @@ from docker.tls import TLSConfig +from ipaddress import ip_address + from twisted.web.http import OK, CREATED from twisted.python.filepath import FilePath from twisted.python.constants import Names, NamedConstant @@ -45,6 +47,7 @@ from ..apiclient import FlockerClient, DatasetState from ..node.script import get_backend, get_api from ..node import dockerpy_client +from ..node.agents.blockdevice import ICloudAPI from .node_scripts import SCRIPTS as NODE_SCRIPTS @@ -826,7 +829,7 @@ def get_file(self, node, path): def connected_cluster( reactor, control_node, certificates_path, num_agent_nodes, - hostname_to_public_address, username='user', + username='user', ): cluster_cert = certificates_path.child(b"cluster.crt") user_cert = certificates_path.child( @@ -869,24 +872,56 @@ def failed_query(failure): failed_query) return d agents_connected = loop_until(reactor, nodes_available) + agents_connected.addCallback(_add_nodes) + return agents_connected + + +def _add_nodes(cluster): + """ + Configure the ``Node`` objects for a newly created ``Cluster`` whose + nodes are known to be alive. + + :param Cluster cluster: Cluster that still needs nodes set. + :return: ``cluster`` updated with appropriate ``nodes`` set. + """ + # By default we just trust address returned by Flocker + def default_get_public_ip(address): + return address - # Extract node hostnames from API that lists nodes. Currently we - # happen know these in advance, but in FLOC-1631 node identification - # will switch to UUIDs instead. - agents_connected.addCallback(lambda _: cluster.current_nodes()) + try: + backend = get_backend_api(None, cluster.cluster_uuid) + except SkipTest: + # Can't load backend, will have to trust Flocker's reported IPs. + get_public_ip = default_get_public_ip + else: + if ICloudAPI.providedBy(backend): + node_ips = list(set(ip_address(i) for i in ips) + for ips in backend.list_live_nodes().values()) + + def get_public_ip(address): + for ips in node_ips: + if ip_address(address) in ips: + return [unicode(ip) for ip in ips + if not any(ip.is_private, ip.is_link_local, + ip.is_loopback)][0] + raise ValueError( + "Couldn't find address in cloud API reported IPs") + else: + get_public_ip = default_get_public_ip def node_from_dict(node): reported_hostname = node["host"] - public_address = hostname_to_public_address.get( - reported_hostname, reported_hostname) + public_address = get_public_ip(reported_hostname) return Node( uuid=node[u"uuid"], public_address=public_address.encode("ascii"), reported_hostname=reported_hostname.encode("ascii"), ) - agents_connected.addCallback(lambda nodes: cluster.set( - "nodes", map(node_from_dict, nodes))) - return agents_connected + + d = cluster.current_nodes() + d.addCallback( + lambda nodes: cluster.set("nodes", map(node_from_dict, nodes))) + return d def _get_test_cluster(reactor): @@ -914,16 +949,11 @@ def _get_test_cluster(reactor): certificates_path = FilePath( environ["FLOCKER_ACCEPTANCE_API_CERTIFICATES_PATH"]) - hostname_to_public_address_env_var = environ.get( - "FLOCKER_ACCEPTANCE_HOSTNAME_TO_PUBLIC_ADDRESS", "{}") - hostname_to_public_address = json.loads(hostname_to_public_address_env_var) - return connected_cluster( reactor, control_node, certificates_path, num_agent_nodes, - hostname_to_public_address ) From 920e2a8a44ef8ccc36c8a36f00d7a57fef4e7fbf Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Wed, 27 Jan 2016 09:53:33 -0500 Subject: [PATCH 04/12] Lint fix. --- flocker/node/agents/ebs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flocker/node/agents/ebs.py b/flocker/node/agents/ebs.py index 8ff888541c..3540ef918e 100644 --- a/flocker/node/agents/ebs.py +++ b/flocker/node/agents/ebs.py @@ -719,7 +719,7 @@ def _wait_for_volume_state_change(operation, start_time = time.time() poll_until( lambda: _reached_end_state( - operation, volume, update, time.time() - start_time, timeout + operation, volume, update, time.time() - start_time, timeout ), itertools.repeat(1) ) From 4e964749cceb3270f41458dcd41eedf4f98d9b0f Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Thu, 28 Jan 2016 11:28:56 -0500 Subject: [PATCH 05/12] A couple minor usage bug fixes. --- flocker/acceptance/testtools.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/flocker/acceptance/testtools.py b/flocker/acceptance/testtools.py index 228dd5fe81..f972cbb8d6 100644 --- a/flocker/acceptance/testtools.py +++ b/flocker/acceptance/testtools.py @@ -872,7 +872,7 @@ def failed_query(failure): failed_query) return d agents_connected = loop_until(reactor, nodes_available) - agents_connected.addCallback(_add_nodes) + agents_connected.addCallback(lambda _: _add_nodes(cluster)) return agents_connected @@ -902,8 +902,8 @@ def get_public_ip(address): for ips in node_ips: if ip_address(address) in ips: return [unicode(ip) for ip in ips - if not any(ip.is_private, ip.is_link_local, - ip.is_loopback)][0] + if not any([ip.is_private, ip.is_link_local, + ip.is_loopback])][0] raise ValueError( "Couldn't find address in cloud API reported IPs") else: From 4e2d3b5947d0fed966c8ac053a234d1a3f74fa7d Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Fri, 29 Jan 2016 10:38:38 -0500 Subject: [PATCH 06/12] Minor clean ups and docs. --- flocker/node/agents/blockdevice.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/flocker/node/agents/blockdevice.py b/flocker/node/agents/blockdevice.py index 8eb33f268c..6b388533e7 100644 --- a/flocker/node/agents/blockdevice.py +++ b/flocker/node/agents/blockdevice.py @@ -1113,6 +1113,13 @@ class ICloudAPI(Interface): This is specifically designed for cloud systems where shut down nodes continue to have volumes attached to them. + + This API is not very well designed, so probably should not be + implemented by third party providers until we do some cleanup. Worth + noting that ``list_live_nodes`` could also be provided by e.g. Swarm + or K8s-specific backend, which suggests ``compute_instance_id`` and + ``list_live_nodes`` should be on a different object than + ``IBlockDeviceAPI``, an object that is loaded by all agents. """ def list_live_nodes(): """ @@ -1123,8 +1130,8 @@ def list_live_nodes(): :returns: A mapping of ``unicode`` compute instance IDs (compatible with those returned by - ``IBlockDeviceAPI.compute_instance_id``) to IPs of those - nodes, also as unicode.. + ``IBlockDeviceAPI.compute_instance_id``) to a list of IPs of + those nodes. The IPs are ``unicode`` as well. """ def start_node(node_id): @@ -1649,8 +1656,8 @@ def is_existing_block_device(dataset_id, path): pass if ICloudAPI.providedBy(self._underlying_blockdevice_api): - live_instances = list( - self._underlying_blockdevice_api.list_live_nodes()) + live_instances = ( + self._underlying_blockdevice_api.list_live_nodes().keys()) else: # Can't know accurately who is alive and who is dead: live_instances = None From 019ce4d1a562b6981f6fc341e7b3b5cb1fd6b752 Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Fri, 29 Jan 2016 10:58:25 -0500 Subject: [PATCH 07/12] Refactor list_live_nodes to return an object. --- flocker/node/agents/blockdevice.py | 18 ++++++---- flocker/node/agents/cinder.py | 14 +++++--- flocker/node/agents/ebs.py | 13 ++++--- flocker/node/agents/test/test_blockdevice.py | 38 +++++++++----------- 4 files changed, 46 insertions(+), 37 deletions(-) diff --git a/flocker/node/agents/blockdevice.py b/flocker/node/agents/blockdevice.py index 6b388533e7..a497fd4953 100644 --- a/flocker/node/agents/blockdevice.py +++ b/flocker/node/agents/blockdevice.py @@ -1103,6 +1103,14 @@ def get_device_path(blockdevice_id): """ +class CloudComputeInstance(PClass): + """ + A compute instance in a cloud. + """ + node_id = field(type=unicode) + ip_addresses = pset_field(unicode) + + class ICloudAPI(Interface): """ Additional functionality provided specifically by cloud-based block @@ -1128,10 +1136,7 @@ def list_live_nodes(): This is used to figure out which nodes are dead, so that other nodes can do the detach. - :returns: A mapping of ``unicode`` compute instance IDs - (compatible with those returned by - ``IBlockDeviceAPI.compute_instance_id``) to a list of IPs of - those nodes. The IPs are ``unicode`` as well. + :returns: A list of ``CloudComputeInstance``. """ def start_node(node_id): @@ -1656,8 +1661,9 @@ def is_existing_block_device(dataset_id, path): pass if ICloudAPI.providedBy(self._underlying_blockdevice_api): - live_instances = ( - self._underlying_blockdevice_api.list_live_nodes().keys()) + live_instances = list( + instance.node_id for instance in + self._underlying_blockdevice_api.list_live_nodes()) else: # Can't know accurately who is alive and who is dead: live_instances = None diff --git a/flocker/node/agents/cinder.py b/flocker/node/agents/cinder.py index dac04d7f48..45eb9d8328 100644 --- a/flocker/node/agents/cinder.py +++ b/flocker/node/agents/cinder.py @@ -38,6 +38,7 @@ from .blockdevice import ( IBlockDeviceAPI, BlockDeviceVolume, UnknownVolume, AlreadyAttachedVolume, UnattachedVolume, UnknownInstanceID, get_blockdevice_volume, ICloudAPI, + CloudComputeInstance, ) from ._logging import ( NOVA_CLIENT_EXCEPTION, KEYSTONE_HTTP_ERROR, COMPUTE_INSTANCE_ID_NOT_FOUND, @@ -689,11 +690,14 @@ def get_device_path(self, blockdevice_id): # ICloudAPI: def list_live_nodes(self): - return {server.id: - list(map( - unicode, _extract_nova_server_addresses(server.addresses))) - for server in self.nova_server_manager.list() - if server.status == u'ACTIVE'} + return [ + CloudComputeInstance( + node_id=server.id, + ips=map(unicode, + _extract_nova_server_addresses(server.addresses))) + for server in self.nova_server_manager.list() + if server.status == u'ACTIVE' + ] def start_node(self, node_id): server = self.nova_server_manager.get(node_id) diff --git a/flocker/node/agents/ebs.py b/flocker/node/agents/ebs.py index 3540ef918e..0b6f32b30e 100644 --- a/flocker/node/agents/ebs.py +++ b/flocker/node/agents/ebs.py @@ -40,7 +40,7 @@ from .blockdevice import ( IBlockDeviceAPI, IProfiledBlockDeviceAPI, BlockDeviceVolume, UnknownVolume, AlreadyAttachedVolume, UnattachedVolume, UnknownInstanceID, - MandatoryProfiles, ICloudAPI, + MandatoryProfiles, ICloudAPI, CloudComputeInstance, ) from flocker.common import poll_until @@ -1363,10 +1363,13 @@ def get_device_path(self, blockdevice_id): def list_live_nodes(self): instances = self.connection.instances.filter( Filters=[{'Name': 'instance-state-name', 'Values': ['running']}]) - return {unicode(instance.id): - [unicode(instance.public_ip_address), - unicode(instance.private_ip_address)] - for instance in instances} + return [ + CloudComputeInstance( + node_id=unicode(instance.id), + ips=[unicode(instance.public_ip_address), + unicode(instance.private_ip_address)]) + for instance in instances + ] @boto3_log def start_node(self, node_id): diff --git a/flocker/node/agents/test/test_blockdevice.py b/flocker/node/agents/test/test_blockdevice.py index 197f2857db..fa276e9bd5 100644 --- a/flocker/node/agents/test/test_blockdevice.py +++ b/flocker/node/agents/test/test_blockdevice.py @@ -87,6 +87,7 @@ ICloudAPI, _SyncToThreadedAsyncCloudAPIAdapter, + CloudComputeInstance, ) from ..loopback import ( @@ -754,11 +755,12 @@ def __init__(self, block_api, live_nodes=()): self.live_nodes = live_nodes def list_live_nodes(self): - result = {self.compute_instance_id(): - set(unicode(i) for i in get_all_ips() - if i != b"127.0.0.1")} - result.update({node: [u"10.1.1.{}".format(i)] - for i, node in enumerate(self.live_nodes)}) + result = [CloudComputeInstance( + node_id=self.compute_instance_id(), + ips=(unicode(i) for i in get_all_ips() if i != b"127.0.0.1"))] + for i, node in enumerate(self.live_nodes): + result.append(CloudComputeInstance( + node_id=node, ips=[u"10.1.1.{}".format(i)])) return result def start_node(self, node_id): @@ -5499,25 +5501,18 @@ def test_interface(self): def test_current_machine_is_live(self): """ - The machine running the test is reported as alive. - """ - d = self.async_cloud_api.list_live_nodes() - d.addCallback(lambda live: - self.assertIn(self.api.compute_instance_id(), live)) - return d - - def test_current_machine_has_appropriate_ip(self): - """ - The machine's known IP is set for the current node. + The machine running the test is reported as alive and has expected + IP addresses. """ local_addresses = set(unicode(i) for i in get_all_ips() if i != b"127.0.0.1") + local_id = self.api.compute_instance_id() d = self.async_cloud_api.list_live_nodes() - d.addCallback( - lambda live: - self.assertTrue( - set(live[self.api.compute_instance_id()]).intersection( - local_addresses))) + + def got_compute_instances(instances): + [instance] = (i for i in instances if i.node_id == local_id) + self.assertTrue(instance.ips.intersection(local_addresses)) + d.addCallback(got_compute_instances) return d def test_list_live_nodes(self): @@ -5525,7 +5520,8 @@ def test_list_live_nodes(self): ``list_live_nodes`` returns an iterable of unicode values. """ live_nodes = list(self.api.list_live_nodes()) - self.assertThat(live_nodes, AllMatch(IsInstance(unicode))) + self.assertThat(live_nodes, + AllMatch(IsInstance(CloudComputeInstance))) return Tests From e2632af792252cbd3f7c2cc419a45bf324610bdc Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Fri, 29 Jan 2016 11:00:07 -0500 Subject: [PATCH 08/12] Some readability cleanups. --- flocker/acceptance/testtools.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/flocker/acceptance/testtools.py b/flocker/acceptance/testtools.py index f972cbb8d6..c745181c50 100644 --- a/flocker/acceptance/testtools.py +++ b/flocker/acceptance/testtools.py @@ -901,21 +901,22 @@ def default_get_public_ip(address): def get_public_ip(address): for ips in node_ips: if ip_address(address) in ips: - return [unicode(ip) for ip in ips - if not any([ip.is_private, ip.is_link_local, - ip.is_loopback])][0] + return list( + unicode(ip) for ip in ips + if not any([ip.is_private, ip.is_link_local, + ip.is_loopback]))[0] raise ValueError( "Couldn't find address in cloud API reported IPs") else: get_public_ip = default_get_public_ip def node_from_dict(node): - reported_hostname = node["host"] - public_address = get_public_ip(reported_hostname) + reported_ip = node["host"] + public_address = get_public_ip(reported_ip) return Node( uuid=node[u"uuid"], public_address=public_address.encode("ascii"), - reported_hostname=reported_hostname.encode("ascii"), + reported_hostname=reported_ip.encode("ascii"), ) d = cluster.current_nodes() From 28d5e019a0b0e725442ee319bff91d0a50748a89 Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Fri, 29 Jan 2016 11:12:53 -0500 Subject: [PATCH 09/12] More changes to match new interface. --- flocker/acceptance/testtools.py | 4 ++-- flocker/node/agents/cinder.py | 5 +++-- flocker/node/agents/ebs.py | 4 ++-- flocker/node/agents/test/test_blockdevice.py | 8 +++++--- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/flocker/acceptance/testtools.py b/flocker/acceptance/testtools.py index c745181c50..5cfe6d8cde 100644 --- a/flocker/acceptance/testtools.py +++ b/flocker/acceptance/testtools.py @@ -895,8 +895,8 @@ def default_get_public_ip(address): get_public_ip = default_get_public_ip else: if ICloudAPI.providedBy(backend): - node_ips = list(set(ip_address(i) for i in ips) - for ips in backend.list_live_nodes().values()) + node_ips = list(set(ip_address(i) for i in instance.ip_addresses) + for instance in backend.list_live_nodes()) def get_public_ip(address): for ips in node_ips: diff --git a/flocker/node/agents/cinder.py b/flocker/node/agents/cinder.py index 45eb9d8328..054a834442 100644 --- a/flocker/node/agents/cinder.py +++ b/flocker/node/agents/cinder.py @@ -693,8 +693,9 @@ def list_live_nodes(self): return [ CloudComputeInstance( node_id=server.id, - ips=map(unicode, - _extract_nova_server_addresses(server.addresses))) + ip_addresses=map( + unicode, + _extract_nova_server_addresses(server.addresses))) for server in self.nova_server_manager.list() if server.status == u'ACTIVE' ] diff --git a/flocker/node/agents/ebs.py b/flocker/node/agents/ebs.py index 0b6f32b30e..5333826f40 100644 --- a/flocker/node/agents/ebs.py +++ b/flocker/node/agents/ebs.py @@ -1366,8 +1366,8 @@ def list_live_nodes(self): return [ CloudComputeInstance( node_id=unicode(instance.id), - ips=[unicode(instance.public_ip_address), - unicode(instance.private_ip_address)]) + ip_addresses=[unicode(instance.public_ip_address), + unicode(instance.private_ip_address)]) for instance in instances ] diff --git a/flocker/node/agents/test/test_blockdevice.py b/flocker/node/agents/test/test_blockdevice.py index fa276e9bd5..1d19b8daaa 100644 --- a/flocker/node/agents/test/test_blockdevice.py +++ b/flocker/node/agents/test/test_blockdevice.py @@ -757,10 +757,11 @@ def __init__(self, block_api, live_nodes=()): def list_live_nodes(self): result = [CloudComputeInstance( node_id=self.compute_instance_id(), - ips=(unicode(i) for i in get_all_ips() if i != b"127.0.0.1"))] + ip_addresses=( + unicode(i) for i in get_all_ips() if i != b"127.0.0.1"))] for i, node in enumerate(self.live_nodes): result.append(CloudComputeInstance( - node_id=node, ips=[u"10.1.1.{}".format(i)])) + node_id=node, ip_addresses=[u"10.1.1.{}".format(i)])) return result def start_node(self, node_id): @@ -5511,7 +5512,8 @@ def test_current_machine_is_live(self): def got_compute_instances(instances): [instance] = (i for i in instances if i.node_id == local_id) - self.assertTrue(instance.ips.intersection(local_addresses)) + self.assertTrue(instance.ip_addresses.intersection( + local_addresses)) d.addCallback(got_compute_instances) return d From 5c9d08fdfb3a54af879bd0b0eb438709c5a076ce Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Mon, 1 Feb 2016 10:06:46 -0500 Subject: [PATCH 10/12] Report trial errors immediately when running acceptance tests. --- build.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.yaml b/build.yaml index ebb7f093b3..d3a7d41a49 100644 --- a/build.yaml +++ b/build.yaml @@ -476,7 +476,7 @@ common_cli: --provider aws --dataset-backend aws --branch ${TRIGGERED_BRANCH} \ --build-server \ http://$(wget -qO- http://instance-data/latest/meta-data/public-ipv4) \ - --config-file /tmp/acceptance.yaml \ + --config-file /tmp/acceptance.yaml --rterrors \ ${ACCEPTANCE_TEST_MODULE} JOB_EXIT_STATUS="$( updateExitStatus $? )" @@ -494,7 +494,7 @@ common_cli: --branch ${TRIGGERED_BRANCH} \ --build-server \ http://$(wget -qO- http://instance-data/latest/meta-data/public-ipv4) \ - --config-file /tmp/acceptance.yaml \ + --config-file /tmp/acceptance.yaml --rterrors \ ${ACCEPTANCE_TEST_MODULE} JOB_EXIT_STATUS="$( updateExitStatus $? )" @@ -517,7 +517,7 @@ common_cli: --branch ${TRIGGERED_BRANCH} \ --build-server \ http://$(wget -qO- http://instance-data/latest/meta-data/public-ipv4) \ - --config-file /tmp/acceptance.yaml \ + --config-file /tmp/acceptance.yaml --rterrors \ ${ACCEPTANCE_TEST_MODULE} JOB_EXIT_STATUS="$( updateExitStatus $? )" From cab81229d40294588e246439408cd890976f5822 Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Mon, 1 Feb 2016 10:15:43 -0500 Subject: [PATCH 11/12] Add some debug statements. --- flocker/acceptance/testtools.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/flocker/acceptance/testtools.py b/flocker/acceptance/testtools.py index 2dd560246f..84a943ff96 100644 --- a/flocker/acceptance/testtools.py +++ b/flocker/acceptance/testtools.py @@ -891,8 +891,9 @@ def default_get_public_ip(address): try: backend = get_backend_api(None, cluster.cluster_uuid) - except SkipTest: + except SkipTest as e: # Can't load backend, will have to trust Flocker's reported IPs. + print "Can't use backend", e get_public_ip = default_get_public_ip else: if ICloudAPI.providedBy(backend): @@ -909,11 +910,13 @@ def get_public_ip(address): raise ValueError( "Couldn't find address in cloud API reported IPs") else: + print "Backend doesn't provide ICloudAPI", backend get_public_ip = default_get_public_ip def node_from_dict(node): reported_ip = node["host"] public_address = get_public_ip(reported_ip) + print reported_ip, get_public_ip, public_address return Node( uuid=node[u"uuid"], public_address=public_address.encode("ascii"), From 39a0003317f7b2f66335e4ad05be8866953faaf2 Mon Sep 17 00:00:00 2001 From: Itamar Turner-Trauring Date: Mon, 1 Feb 2016 10:31:15 -0500 Subject: [PATCH 12/12] Doesn't work, can't be bothered to figure out why. --- build.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.yaml b/build.yaml index d3a7d41a49..ebb7f093b3 100644 --- a/build.yaml +++ b/build.yaml @@ -476,7 +476,7 @@ common_cli: --provider aws --dataset-backend aws --branch ${TRIGGERED_BRANCH} \ --build-server \ http://$(wget -qO- http://instance-data/latest/meta-data/public-ipv4) \ - --config-file /tmp/acceptance.yaml --rterrors \ + --config-file /tmp/acceptance.yaml \ ${ACCEPTANCE_TEST_MODULE} JOB_EXIT_STATUS="$( updateExitStatus $? )" @@ -494,7 +494,7 @@ common_cli: --branch ${TRIGGERED_BRANCH} \ --build-server \ http://$(wget -qO- http://instance-data/latest/meta-data/public-ipv4) \ - --config-file /tmp/acceptance.yaml --rterrors \ + --config-file /tmp/acceptance.yaml \ ${ACCEPTANCE_TEST_MODULE} JOB_EXIT_STATUS="$( updateExitStatus $? )" @@ -517,7 +517,7 @@ common_cli: --branch ${TRIGGERED_BRANCH} \ --build-server \ http://$(wget -qO- http://instance-data/latest/meta-data/public-ipv4) \ - --config-file /tmp/acceptance.yaml --rterrors \ + --config-file /tmp/acceptance.yaml \ ${ACCEPTANCE_TEST_MODULE} JOB_EXIT_STATUS="$( updateExitStatus $? )"