From: Claudio-Daniel Freire Date: Wed, 14 Sep 2011 04:57:40 +0000 (+0200) Subject: Merge with head X-Git-Tag: nepi-3.0.0~234 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=0c908df356a6e40f6a3d69c46b5a14afc24df62b;hp=7ba1f1c912766fa0b9c5227418ec9fa1fa7f8b4e;p=nepi.git Merge with head --- diff --git a/src/nepi/testbeds/planetlab/execute.py b/src/nepi/testbeds/planetlab/execute.py index 27ed23d7..dcb5023d 100644 --- a/src/nepi/testbeds/planetlab/execute.py +++ b/src/nepi/testbeds/planetlab/execute.py @@ -256,9 +256,18 @@ class TestbedController(testbed_impl.TestbedController): if nodes and reqs: if recover: raise RuntimeError, "Impossible to recover: unassigned host for Nodes %r" % (nodes,) + + def pickbest(fullset, nreq, node=nodes[0]): + if len(fullset) > nreq: + fullset = zip(node.rate_nodes(fullset),fullset) + fullset.sort(reverse=True) + del fullset[nreq:] + return set(map(operator.itemgetter(1),fullset)) + else: + return fullset try: - solution = resourcealloc.alloc(reqs) + solution = resourcealloc.alloc(reqs, sample=pickbest) except resourcealloc.ResourceAllocationError: # Failed, try again with all nodes reqs = [] @@ -267,7 +276,7 @@ class TestbedController(testbed_impl.TestbedController): candidates -= reserved reqs.append(candidates) - solution = resourcealloc.alloc(reqs) + solution = resourcealloc.alloc(reqs, sample=pickbest) to_provision.update(solution) # Do assign nodes diff --git a/src/nepi/testbeds/planetlab/node.py b/src/nepi/testbeds/planetlab/node.py index 5e1445ec..b9a7d09f 100644 --- a/src/nepi/testbeds/planetlab/node.py +++ b/src/nepi/testbeds/planetlab/node.py @@ -64,7 +64,15 @@ class Node(object): 'maxLoad' : ('load%(timeframe)s', '[value'), 'minCpu' : ('cpu%(timeframe)s', ']value'), 'maxCpu' : ('cpu%(timeframe)s', '[value'), - } + } + + RATE_FACTORS = ( + # (, , ) + ('bw%(timeframe)s', -0.001, 1024.0), + ('cpu%(timeframe)s', 0.1, 40.0), + ('load%(timeframe)s', -0.2, 3.0), + ('reliability%(timeframe)s', 1, 100.0), + ) DEPENDS_PIDFILE = '/tmp/nepi-depends.pid' DEPENDS_LOGFILE = '/tmp/nepi-depends.log' @@ -316,6 +324,28 @@ class Node(object): self._node_id = None self.__dict__.update(self.__orig_attrs) + def rate_nodes(self, nodes): + rates = collections.defaultdict(int) + tags = collections.defaultdict(dict) + replacements = {'timeframe':self.timeframe} + tagnames = [ tagname % replacements + for tagname, weight, default in self.RATE_FACTORS ] + + taginfo = self._api.GetNodeTags( + node_id=list(nodes), + tagname=tagnames, + fields=('node_id','tagname','value')) + + for node, tagname, value in taginfo: + tags[tagname][int(node)] = float(value) + + for tagname, weight, default in self.RATE_FACTORS: + taginfo = tags[tagname].get + for node in nodes: + rates[node] += weight * taginfo(node,default) + + return map(rates.__getitem__, nodes) + def fetch_node_info(self): orig_attrs = {} diff --git a/src/nepi/testbeds/planetlab/resourcealloc.py b/src/nepi/testbeds/planetlab/resourcealloc.py index bafde65a..a5385c3d 100644 --- a/src/nepi/testbeds/planetlab/resourcealloc.py +++ b/src/nepi/testbeds/planetlab/resourcealloc.py @@ -32,7 +32,7 @@ def _log(logstream, message, *args, **kwargs): logstream.write(message) logstream.write('\n') -def alloc(requests, logstream = None, nonseparable = False, saveinteresting = None, backtracklim = 100000000, verbose = True): +def alloc(requests, logstream = None, nonseparable = False, saveinteresting = None, backtracklim = 100000000, verbose = True, sample = random.sample): """ Takes an iterable over requests, which are iterables of candidate node ids, and returns a specific node id for each request (if successful). @@ -267,7 +267,7 @@ def alloc(requests, logstream = None, nonseparable = False, saveinteresting = No part = Pavail[i] if len(part) < nreq: raise AssertionError, "Cannot allocate resources for supposedly valid solution!" - assigned = set(random.sample(part, nreq)) + assigned = set(sample(part, nreq)) psol |= assigned part -= assigned solution[c] = psol