Filter blacklisted nodes in util.getNodes
[nepi.git] / src / nepi / testbeds / planetlab / util.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 from constants import TESTBED_ID, TESTBED_VERSION
5 from nepi.core import testbed_impl
6 from nepi.core.metadata import Parallel
7 from nepi.util.constants import TIME_NOW
8 from nepi.util.graphtools import mst
9 from nepi.util import ipaddr2
10 from nepi.util import environ
11 from nepi.util.parallel import ParallelRun
12 import sys
13 import os
14 import os.path
15 import time
16 import resourcealloc
17 import collections
18 import operator
19 import functools
20 import socket
21 import struct
22 import tempfile
23 import subprocess
24 import random
25 import shutil
26 import logging
27 import metadata
28 import weakref
29
30 def getAPI(user, pass_):
31     import plcapi
32     return plcapi.PLCAPI(username=user, password=pass_)
33
34 def filterBlacklist(candidates):
35     blpath = environ.homepath('plblacklist')
36     
37     try:
38         bl = open(blpath, "r")
39     except:
40         return candidates
41         
42     try:
43         blacklist = set(
44             map(int,
45                 map(str.strip, bl.readlines())
46             )
47         )
48         return [ x for x in candidates if x not in blacklist ]
49     finally:
50         bl.close()
51
52 def getNodes(api, num, **constraints):
53     # Now do the backtracking search for a suitable solution
54     # First with existing slice nodes
55     reqs = []
56     nodes = []
57     
58     import node as Node
59         
60     for i in xrange(num):
61         node = Node.Node(api)
62         node.min_num_external_interface = 1
63         nodes.append(node)
64     
65     node = nodes[0]
66     candidates = filterBlacklist(node.find_candidates())
67     reqs = [candidates] * num
68
69     def pickbest(fullset, nreq, node=nodes[0]):
70         if len(fullset) > nreq:
71             fullset = zip(node.rate_nodes(fullset),fullset)
72             fullset.sort(reverse=True)
73             del fullset[nreq:]
74             return set(map(operator.itemgetter(1),fullset))
75         else:
76             return fullset
77     
78     solution = resourcealloc.alloc(reqs, sample=pickbest)
79     
80     # Do assign nodes
81     runner = ParallelRun(maxthreads=4)
82     for node, node_id in zip(nodes, solution):
83         runner.put(node.assign_node_id, node_id)
84     runner.join()
85     
86     return nodes
87
88 def getSpanningTree(nodes, root = None, maxbranching = 2, hostgetter = operator.attrgetter('hostname')):
89     if not root:
90         # Pick root (deterministically)
91         root = min(nodes, key=hostgetter)
92     
93     # Obtain all IPs in numeric format
94     # (which means faster distance computations)
95     for node in nodes:
96         node._ip = socket.gethostbyname(hostgetter(node))
97         node._ip_n = struct.unpack('!L', socket.inet_aton(node._ip))[0]
98     
99     # Compute plan
100     # NOTE: the plan is an iterator
101     plan = mst.mst(
102         nodes,
103         lambda a,b : ipaddr2.ipdistn(a._ip_n, b._ip_n),
104         root = root,
105         maxbranching = maxbranching)
106
107     return plan
108