def getNodes(api, num, **constraints): # Now do the backtracking search for a suitable solution # First with existing slice nodes reqs = [] nodes = [] import node as Node for i in xrange(num): node = Node.Node(api) node.min_num_external_interface = 1 nodes.append(node) node = nodes[0] candidates = filterBlacklist(node.find_candidates()) reqs = [candidates] * num 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 solution = resourcealloc.alloc(reqs, sample=pickbest) # Do assign nodes runner = ParallelRun(maxthreads=4) for node, node_id in zip(nodes, solution): runner.put(node.assign_node_id, node_id) runner.join() return nodes
def getNodes(api, num, **constraints): # Now do the backtracking search for a suitable solution # First with existing slice nodes reqs = [] nodes = [] import node as Node for i in xrange(num): node = Node.Node(api) node.min_num_external_interface = 1 nodes.append(node) node = nodes[0] candidates = filterBlacklist(node.find_candidates()) reqs = [candidates] * num 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 solution = resourcealloc.alloc(reqs, sample=pickbest) # Do assign nodes runner = ParallelRun(maxthreads=4) for node, node_id in zip(nodes, solution): runner.put(node.assign_node_id, node_id) runner.join() return nodes
def do_resource_discovery(self, recover = False): to_provision = self._to_provision = set() reserved = set(self._blacklist) for guid, node in self._elements.iteritems(): if isinstance(node, self._node.Node) and node._node_id is not None: reserved.add(node.hostname) # Initial algo: # look for perfectly defined nodes # (ie: those with only one candidate) reserve_lock = threading.RLock() def assignifunique(guid, node): # Try existing nodes first # If we have only one candidate, simply use it candidates = node.find_candidates( filter_slice_id = self.slice_id) node_id = None candidate_hosts = set(candidates.keys() if candidates else []) reserve_lock.acquire() try: candidate_hosts -= reserved if len(candidate_hosts) == 1: hostname = iter(candidate_hosts).next() node_id = candidates[hostname] reserved.add(hostname) elif not candidate_hosts: # Try again including unassigned nodes reserve_lock.release() try: candidates = node.find_candidates() finally: reserve_lock.acquire() candidate_hosts = set(candidates.keys() if candidates else []) candidate_hosts -= reserved if len(candidate_hosts) > 1: return if len(candidate_hosts) == 1: hostname = iter(candidate_hosts).next() node_id = candidates[hostname] to_provision.add(node_id) reserved.add(hostname) elif not candidates: raise RuntimeError, "Cannot assign resources for node %s, no candidates with %s" % (guid, node.make_filter_description()) finally: reserve_lock.release() if node_id is not None: node.assign_node_id(node_id) runner = ParallelRun(maxthreads=4) # don't overload the PLC API, just 4 threads to hide latencies and that's it runner.start() for guid, node in self._elements.iteritems(): if isinstance(node, self._node.Node) and node._node_id is None: runner.put(assignifunique, guid, node) runner.sync() # Now do the backtracking search for a suitable solution # First with existing slice nodes reqs = [] nodes = [] def genreqs(node, filter_slice_id=None): # Try existing nodes first # If we have only one candidate, simply use it candidates = node.find_candidates( filter_slice_id = filter_slice_id) for r in reserved: if candidates.has_key(r): del candidates[r] reqs.append(candidates.values()) nodes.append(node) for guid, node in self._elements.iteritems(): if isinstance(node, self._node.Node) and node._node_id is None: runner.put(genreqs, node, self.slice_id) runner.sync() 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, sample=pickbest) except resourcealloc.ResourceAllocationError: # Failed, try again with all nodes reqs = [] for node in nodes: runner.put(genreqs, node) runner.sync() solution = resourcealloc.alloc(reqs, sample=pickbest) to_provision.update(solution) # Do assign nodes for node, node_id in zip(nodes, solution): runner.put(node.assign_node_id, node_id) runner.join()