3 The sliver manager has several functions. It is responsible for
4 creating, resource limiting, starting, stopping, and destroying
5 slivers. It provides an API for users to access these functions and
6 also to make inter-sliver resource loans. The sliver manager is also
7 responsible for handling delegation accounts.
20 DEFAULT_ALLOCATION = {
24 'cpu_share': 32, # proportional share
25 # bandwidth parameters
26 'net_min': bwlimit.bwmin, # bps
27 'net_max': bwlimit.bwmax, # bps
28 'net_share': 1, # proportional share
29 # bandwidth parameters over routes exempt from node bandwidth limits
30 'net2_min': bwlimit.bwmin, # bps
31 'net2_max': bwlimit.bwmax, # bps
32 'net2_share': 1, # proportional share
33 'disk_max': 5000000 # bytes
36 start_requested = False # set to True in order to request that all slivers be started
39 @database.synchronized
40 def GetSlivers_callback(data, fullupdate=True):
41 """This function has two purposes. One, convert GetSlivers() data into a more convenient format. Two, even if no updates are coming in, use the GetSlivers() heartbeat as a cue to scan for expired slivers."""
45 f = open('/etc/planetlab/node_id')
46 try: node_id = int(f.read())
48 except: logger.log_exc()
50 # query running network interfaces
52 ips = dict(zip(devs.values(), devs.keys()))
55 macs[sioc.gifhwaddr(dev).lower()] = dev
58 if d['node_id'] != node_id: continue
60 # XXX Exempt Internet2 destinations from node bwlimits
61 # bwlimit.exempt_init('Internet2', internet2_ips)
63 for network in d['networks']:
64 if macs.has_key(network['mac'].lower()):
65 dev = macs[network['mac'].lower()]
66 elif ips.has_key(network['ip']):
67 dev = ips[network['ip']]
69 logger.log('%s: no such interface with address %s/%s' % (self.name, network['ip'], network['mac']))
73 old_bwlimit = bwlimit.get_bwcap(dev)
77 if network['bwlimit'] is None:
78 new_bwlimit = bwlimit.bwmax
80 new_bwlimit = network['bwlimit']
82 if old_bwlimit != new_bwlimit:
83 # reinitialize bandwidth limits
84 bwlimit.init(dev, new_bwlimit)
86 # XXX this should trigger an rspec refresh in case
87 # some previously invalid sliver bwlimit is now valid
88 # again, or vice-versa.
90 for sliver in d['slivers']:
92 rec.setdefault('timestamp', d['timestamp'])
94 # convert attributes field to a proper dict
96 for attr in rec.pop('attributes'): attr_dict[attr['name']] = attr['value']
99 keys = rec.pop('keys')
100 rec.setdefault('keys', '\n'.join([key_struct['key'] for key_struct in keys]))
102 rec.setdefault('type', attr_dict.get('type', 'sliver.VServer'))
103 rec.setdefault('vref', attr_dict.get('vref', 'default'))
104 rec.setdefault('initscript', attr_dict.get('initscript', ''))
105 rec.setdefault('delegations', []) # XXX - delegation not yet supported
107 # extract the implied rspec
110 for resname, default_amt in DEFAULT_ALLOCATION.iteritems():
111 try: amt = int(attr_dict[resname])
112 except (KeyError, ValueError): amt = default_amt
114 database.db.deliver_record(rec)
115 if fullupdate: database.db.set_min_timestamp(d['timestamp'])
118 # handle requested startup
119 global start_requested
121 start_requested = False
123 for name in database.db.iterkeys():
124 accounts.get(name).start(delay=cumulative_delay)
125 cumulative_delay += 3
127 def deliver_ticket(data): return GetSlivers_callback(data, fullupdate=False)
130 def start(options, config):
131 accounts.register_class(sliver_vs.Sliver_VS)
132 accounts.register_class(delegate.Delegate)
133 global start_requested
134 start_requested = options.startup
136 api.deliver_ticket = deliver_ticket