From: Claudio-Daniel Freire Date: Fri, 27 May 2011 10:51:48 +0000 (+0200) Subject: Ticket #22: complitid X-Git-Tag: nepi_v2_1~56 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=729f82f5c52c2f7820750e70910987dff2eecab3;p=nepi.git Ticket #22: complitid --- diff --git a/src/nepi/testbeds/planetlab/execute.py b/src/nepi/testbeds/planetlab/execute.py index d9506f5b..15065b89 100644 --- a/src/nepi/testbeds/planetlab/execute.py +++ b/src/nepi/testbeds/planetlab/execute.py @@ -6,6 +6,7 @@ from nepi.core import testbed_impl from nepi.util.constants import TIME_NOW import os import time +import resourcealloc class TestbedController(testbed_impl.TestbedController): def __init__(self, testbed_version): @@ -80,12 +81,11 @@ class TestbedController(testbed_impl.TestbedController): super(TestbedController, self).do_preconfigure() def do_resource_discovery(self): - # Do what? - - # Provisional algo: + to_provision = self._to_provision = set() + + # Initial algo: # look for perfectly defined nodes # (ie: those with only one candidate) - to_provision = self._to_provision = set() for guid, node in self._elements.iteritems(): if isinstance(node, self._node.Node) and node._node_id is None: # Try existing nodes first @@ -98,13 +98,43 @@ class TestbedController(testbed_impl.TestbedController): # Try again including unassigned nodes candidates = node.find_candidates() if len(candidates) > 1: - raise RuntimeError, "Cannot assign resources for node %s, too many candidates" % (guid,) + continue if len(candidates) == 1: node_id = iter(candidates).next() node.assign_node_id(node_id) to_provision.add(node_id) elif not candidates: raise RuntimeError, "Cannot assign resources for node %s, no candidates" % (guid,) + + # Now do the backtracking search for a suitable solution + # First with existing slice nodes + reqs = [] + nodes = [] + for guid, node in self._elements.iteritems(): + if isinstance(node, self._node.Node) and node._node_id is None: + # Try existing nodes first + # If we have only one candidate, simply use it + candidates = node.find_candidates( + filter_slice_id = self.slice_id) + reqs.append(candidates) + nodes.append(node) + + if nodes and reqs: + try: + solution = resourcealloc.alloc(reqs) + except resourcealloc.ResourceAllocationError: + # Failed, try again with all nodes + reqs = [] + for node in nodes: + candidates = node.find_candidates() + reqs.append(candidates) + + solution = resourcealloc.alloc(reqs) + to_provision.update(solution) + + # Do assign nodes + for node, node_id in zip(nodes, solution): + node.assign_node_id(node_id) def do_provisioning(self): if self._to_provision: diff --git a/src/nepi/testbeds/planetlab/node.py b/src/nepi/testbeds/planetlab/node.py index 0b5b9de8..08ec7a7c 100644 --- a/src/nepi/testbeds/planetlab/node.py +++ b/src/nepi/testbeds/planetlab/node.py @@ -9,6 +9,7 @@ import time import os import collections import cStringIO +import resourcealloc from nepi.util import server @@ -108,6 +109,10 @@ class Node(object): if filter_slice_id: basefilters['|slice_ids'] = (filter_slice_id,) + # only pick healthy nodes + basefilters['run_level'] = 'boot' + basefilters['boot_state'] = 'boot' + # keyword-only "pseudofilters" extra = {} if self.site: diff --git a/test/testbeds/planetlab/execute.py b/test/testbeds/planetlab/execute.py index 920ef030..ecff9e6d 100755 --- a/test/testbeds/planetlab/execute.py +++ b/test/testbeds/planetlab/execute.py @@ -509,6 +509,63 @@ echo 'OKIDOKI' # asserts at the end, to make sure there's proper cleanup self.assertEqual(ping_result, "") + + @test_util.skipUnless(test_util.pl_auth() is not None, "Test requires PlanetLab authentication info (PL_USER and PL_PASS environment variables)") + def test_discovery(self): + instance = self.make_instance() + + instance.defer_create(2, "Node") + instance.defer_create_set(2, "operatingSystem", "f12") + instance.defer_create(3, "Node") + instance.defer_create_set(3, "operatingSystem", "f12") + instance.defer_create(4, "NodeInterface") + instance.defer_connect(2, "devs", 4, "node") + instance.defer_create(5, "NodeInterface") + instance.defer_connect(3, "devs", 5, "node") + instance.defer_create(6, "Internet") + instance.defer_connect(4, "inet", 6, "devs") + instance.defer_connect(5, "inet", 6, "devs") + instance.defer_create(7, "Application") + instance.defer_create_set(7, "command", "ping -qc1 {#[GUID-5].addr[0].[Address]#}") + instance.defer_add_trace(7, "stdout") + instance.defer_add_trace(7, "stderr") + instance.defer_connect(7, "node", 2, "apps") + + comp_result = r"""PING .* \(.*\) \d*\(\d*\) bytes of data. + +--- .* ping statistics --- +1 packets transmitted, 1 received, 0% packet loss, time \d*ms.* +""" + + try: + instance.do_setup() + instance.do_create() + instance.do_connect_init() + instance.do_connect_compl() + instance.do_preconfigure() + + # Manually replace netref + instance.set(7, "command", + instance.get(7, "command") + .replace("{#[GUID-5].addr[0].[Address]#}", + instance.get_address(5, 0, "Address") ) + ) + + instance.do_configure() + + instance.do_prestart() + instance.start() + while instance.status(7) != STATUS_FINISHED: + time.sleep(0.5) + ping_result = instance.trace(7, "stdout") or "" + instance.stop() + finally: + instance.shutdown() + + # asserts at the end, to make sure there's proper cleanup + self.assertTrue(re.match(comp_result, ping_result, re.MULTILINE), + "Unexpected trace:\n" + ping_result) + if __name__ == '__main__':