From: Faiyaz Ahmed Date: Mon, 26 Feb 2007 18:04:40 +0000 (+0000) Subject: Bump release. Merge from HEAD. X-Git-Tag: planetlab-4_0-rc2~17 X-Git-Url: http://git.onelab.eu/?p=nodemanager.git;a=commitdiff_plain;h=f211fe036f17f4758df731fc6d8dbf3d64ca96ac Bump release. Merge from HEAD. --- diff --git a/NodeManager.spec b/NodeManager.spec index c5f2f40..1c1fb34 100644 --- a/NodeManager.spec +++ b/NodeManager.spec @@ -1,6 +1,6 @@ Summary: PlanetLab Node Manager Name: NodeManager -Version: 1.1 +Version: 1.2 Release: 1%{?pldistro:.%{pldistro}}%{?date:.%{date}} License: PlanetLab Group: System Environment/Daemons diff --git a/accounts.py b/accounts.py index fe0af53..1b8c8a8 100644 --- a/accounts.py +++ b/accounts.py @@ -67,7 +67,7 @@ class Account: self.configure(rec) @staticmethod - def create(name): abstract + def create(name, vref = None): abstract @staticmethod def destroy(name): abstract diff --git a/api.py b/api.py index 8e8794a..5c4ab4a 100644 --- a/api.py +++ b/api.py @@ -147,7 +147,7 @@ class APIRequestHandler(SimpleXMLRPCServer.SimpleXMLRPCRequestHandler): target_name = args[0] target_rec = database.db.get(target_name) if not (target_rec and target_rec['type'].startswith('sliver.')): raise xmlrpclib.Fault(102, 'Invalid argument: the first argument must be a sliver name.') - if not (caller_name in (args[0], 'root') or (caller_name, method_name) in target_rec['delegations']): raise xmlrpclib.Fault(108, 'Permission denied.') + if not (caller_name in (args[0], 'root') or (caller_name, method_name) in target_rec['delegations'] or (caller_name == 'utah_elab_delegate' and target_name.startswith('utah_elab_'))): raise xmlrpclib.Fault(108, 'Permission denied.') result = method(target_rec, *args[1:]) else: result = method(*args) if result == None: result = 1 diff --git a/bwmon.py b/bwmon.py index 28c7341..68a118c 100644 --- a/bwmon.py +++ b/bwmon.py @@ -15,7 +15,7 @@ # Faiyaz Ahmed # Copyright (C) 2004-2006 The Trustees of Princeton University # -# $Id: bwmon.py,v 1.2 2007/02/07 18:12:02 faiyaza Exp $ +# $Id$ # import os @@ -24,11 +24,22 @@ import time import pickle import database -#import socket +import socket #import xmlrpclib import bwlimit +import logger from sets import Set +try: + sys.path.append("/etc/planetlab") + from plc_config import * +except: + logger.log("bwmon: Warning: Configuration file /etc/planetlab/plc_config.py not found") + PLC_NAME = "PlanetLab" + PLC_SLICE_PREFIX = "pl" + PLC_MAIL_SUPPORT_ADDRESS = "support@planet-lab.org" + PLC_MAIL_SLICE_ADDRESS = "SLICE@slices.planet-lab.org" + # Utility functions #from pl_mom import * @@ -43,11 +54,12 @@ verbose = 0 datafile = "/var/lib/misc/bwmon.dat" #nm = None -# Burst to line rate (or node cap). Set by NM. -default_MaxRate = bwlimit.get_bwcap() -default_Maxi2Rate = bwlimit.bwmax +# Burst to line rate (or node cap). Set by NM. in KBit/s +default_MaxRate = int(bwlimit.get_bwcap() / 1000) +default_Maxi2Rate = int(bwlimit.bwmax / 1000) # Min rate 8 bits/s -default_MinRate = 8 +default_MinRate = 0 +default_Mini2Rate = 0 # 5.4 Gbyte per day. 5.4 * 1024 k * 1024M * 1024G # 5.4 Gbyte per day max allowed transfered per recording period default_MaxKByte = 5662310 @@ -81,6 +93,78 @@ footer = \ %(date)s %(hostname)s bwcap %(slice)s """.lstrip() +def format_bytes(bytes, si = True): + """ + Formats bytes into a string + """ + if si: + kilo = 1000. + else: + # Officially, a kibibyte + kilo = 1024. + + if bytes >= (kilo * kilo * kilo): + return "%.1f GB" % (bytes / (kilo * kilo * kilo)) + elif bytes >= 1000000: + return "%.1f MB" % (bytes / (kilo * kilo)) + elif bytes >= 1000: + return "%.1f KB" % (bytes / kilo) + else: + return "%.0f bytes" % bytes + +def format_period(seconds): + """ + Formats a period in seconds into a string + """ + + if seconds == (24 * 60 * 60): + return "day" + elif seconds == (60 * 60): + return "hour" + elif seconds > (24 * 60 * 60): + return "%.1f days" % (seconds / 24. / 60. / 60.) + elif seconds > (60 * 60): + return "%.1f hours" % (seconds / 60. / 60.) + elif seconds > (60): + return "%.1f minutes" % (seconds / 60.) + else: + return "%.0f seconds" % seconds + +def slicemail(slice, subject, body): + sendmail = os.popen("/usr/sbin/sendmail -N never -t -f%s" % PLC_MAIL_SUPPORT_ADDRESS, "w") + + # PLC has a separate list for pl_mom messages + if PLC_MAIL_SUPPORT_ADDRESS == "support@planet-lab.org": + to = ["pl-mom@planet-lab.org"] + else: + to = [PLC_MAIL_SUPPORT_ADDRESS] + + if slice is not None and slice != "root": + to.append(PLC_MAIL_SLICE_ADDRESS.replace("SLICE", slice)) + + header = {'from': "%s Support <%s>" % (PLC_NAME, PLC_MAIL_SUPPORT_ADDRESS), + 'to': ", ".join(to), + 'version': sys.version.split(" ")[0], + 'subject': subject} + + # Write headers + sendmail.write( +""" +Content-type: text/plain +From: %(from)s +Reply-To: %(from)s +To: %(to)s +X-Mailer: Python/%(version)s +Subject: %(subject)s + +""".lstrip() % header) + + # Write body + sendmail.write(body) + # Done + sendmail.close() + + class Slice: """ Stores the last recorded bandwidth parameters of a slice. @@ -100,7 +184,7 @@ class Slice: """ - def __init__(self, xid, name, maxrate, maxi2rate, bytes, i2bytes, data): + def __init__(self, xid, name, data): self.xid = xid self.name = name self.time = 0 @@ -109,6 +193,7 @@ class Slice: self.MaxRate = default_MaxRate self.MinRate = default_MinRate self.Maxi2Rate = default_Maxi2Rate + self.Mini2Rate = default_Mini2Rate self.MaxKByte = default_MaxKByte self.ThreshKByte = default_ThreshKByte self.Maxi2KByte = default_Maxi2KByte @@ -116,8 +201,14 @@ class Slice: self.Share = default_Share self.emailed = False - # Get real values where applicable - self.reset(maxrate, maxi2rate, bytes, i2bytes, data) + self.updateSliceAttributes(data) + bwlimit.set(xid = self.xid, + minrate = self.MinRate, + maxrate = self.MaxRate, + maxexemptrate = self.Maxi2Rate, + minexemptrate = self.Mini2Rate, + share = self.Share) + def __repr__(self): return self.name @@ -125,28 +216,49 @@ class Slice: @database.synchronized def updateSliceAttributes(self, data): for sliver in data['slivers']: - if sliver['name'] == self.name: + if sliver['name'] == self.name: for attribute in sliver['attributes']: - if attribute['name'] == 'net_min_rate': - self.MinRate = attribute['value'] - elif attribute['name'] == 'net_max_rate': - self.MaxRate = attribute['value'] + if attribute['name'] == 'net_min_rate': + self.MinRate = int(attribute['value']) + logger.log("bwmon: Updating %s. Min Rate = %s" \ + %(self.name, self.MinRate)) + elif attribute['name'] == 'net_max_rate': + self.MaxRate = int(attribute['value']) + logger.log("bwmon: Updating %s. Max Rate = %s" \ + %(self.name, self.MaxRate)) elif attribute['name'] == 'net_i2_min_rate': - self.Mini2Rate = attribute['value'] + self.Mini2Rate = int(attribute['value']) + logger.log("bwmon: Updating %s. Min i2 Rate = %s" \ + %(self.name, self.Mini2Rate)) elif attribute['name'] == 'net_i2_max_rate': - self.Maxi2Rate = attribute['value'] - elif attribute['name'] == 'net_max_kbyte': - self.MaxKbyte = attribute['value'] - elif attribute['name'] == 'net_i2_max_kbyte': - self.Maxi2KByte = attribute['value'] - elif attribute['name'] == 'net_thresh_kbyte': - self.ThreshKByte = attribute['value'] + self.Maxi2Rate = int(attribute['value']) + logger.log("bwmon: Updating %s. Max i2 Rate = %s" \ + %(self.name, self.Maxi2Rate)) + elif attribute['name'] == 'net_max_kbyte': + self.MaxKByte = int(attribute['value']) + logger.log("bwmon: Updating %s. Max KByte lim = %s" \ + %(self.name, self.MaxKByte)) + elif attribute['name'] == 'net_i2_max_kbyte': + self.Maxi2KByte = int(attribute['value']) + logger.log("bwmon: Updating %s. Max i2 KByte = %s" \ + %(self.name, self.Maxi2KByte)) + elif attribute['name'] == 'net_thresh_kbyte': + self.ThreshKByte = int(attribute['value']) + logger.log("bwmon: Updating %s. Thresh KByte = %s" \ + %(self.name, self.ThreshKByte)) elif attribute['name'] == 'net_i2_thresh_kbyte': - self.Threshi2KByte = attribute['value'] - elif attribute['name'] == 'net_share': - self.Share = attribute['value'] - elif attribute['name'] == 'net_i2_share': - self.Sharei2 = attribute['value'] + self.Threshi2KByte = int(attribute['value']) + logger.log("bwmon: Updating %s. i2 Thresh KByte = %s" \ + %(self.name, self.Threshi2KByte)) + elif attribute['name'] == 'net_share': + self.Share = int(attribute['value']) + logger.log("bwmon: Updating %s. Net Share = %s" \ + %(self.name, self.Share)) + elif attribute['name'] == 'net_i2_share': + self.Sharei2 = int(attribute['value']) + logger.log("bwmon: Updating %s. Net i2 Share = %s" \ + %(self.name, self.i2Share)) + def reset(self, runningmaxrate, runningmaxi2rate, usedbytes, usedi2bytes, data): """ @@ -166,18 +278,19 @@ class Slice: # Reset email self.emailed = False - + maxrate = self.MaxRate * 1000 + maxi2rate = self.Maxi2Rate * 1000 # Reset rates. if (self.MaxRate != runningmaxrate) or (self.Maxi2Rate != runningmaxi2rate): - print "%s reset to %s/%s" % \ + logger.log("bwmon: %s reset to %s/%s" % \ (self.name, - bwlimit.format_tc_rate(self.MaxRate), - bwlimit.format_tc_rate(self.Maxi2Rate)) + bwlimit.format_tc_rate(maxrate), + bwlimit.format_tc_rate(maxi2rate))) bwlimit.set(xid = self.xid, - minrate = self.MinRate, - maxrate = self.MaxRate, - maxexemptrate = self.Maxi2Rate, - minexemptrate = self.Mini2Rate, + minrate = self.MinRate * 1000, + maxrate = self.MaxRate * 1000, + maxexemptrate = self.Maxi2Rate * 1000, + minexemptrate = self.Mini2Rate * 1000, share = self.Share) def update(self, runningmaxrate, runningmaxi2rate, usedbytes, usedi2bytes, data): @@ -197,58 +310,58 @@ class Slice: 'date': time.asctime(time.gmtime()) + " GMT", 'period': format_period(period)} - if usedi2bytes >= (self.usedbytes + self.ByteThresh): + if usedbytes >= (self.bytes + (self.ThreshKByte * 1024)): maxbyte = self.MaxKByte * 1024 - bytesused = bytes - self.bytes + bytesused = usedbytes - self.bytes timeused = int(time.time() - self.time) new_maxrate = int(((maxbyte - bytesused) * 8)/(period - timeused)) if new_maxrate < self.MinRate: new_maxrate = self.MinRate else: - new_maxrate = self.MaxRate + new_maxrate = self.MaxRate * 1000 # Format template parameters for low bandwidth message params['class'] = "low bandwidth" params['bytes'] = format_bytes(usedbytes - self.bytes) params['maxrate'] = bwlimit.format_tc_rate(runningmaxrate) - params['limit'] = format_bytes(self.MaxKByte) + params['limit'] = format_bytes(self.MaxKByte * 1024) params['new_maxrate'] = bwlimit.format_tc_rate(new_maxrate) if verbose: - print "%(slice)s %(class)s " \ + logger.log("bwmon: %(slice)s %(class)s " \ "%(bytes)s of %(limit)s (%(new_maxrate)s/s maxrate)" % \ - params + params) # Cap low bandwidth burst rate if new_maxrate != runningmaxrate: message += template % params - print "%(slice)s %(class)s capped at %(new_maxrate)s/s " % params + logger.log("bwmon: %(slice)s %(class)s capped at %(new_maxrate)s/s " % params) - if usedi2bytes >= (self.i2bytes + self.Threshi2KBytes): + if usedi2bytes >= (self.i2bytes + (self.Threshi2KByte * 1024)): maxi2byte = self.Maxi2KByte * 1024 - i2bytesused = i2bytes - self.i2bytes + i2bytesused = usedi2bytes - self.i2bytes timeused = int(time.time() - self.time) new_maxi2rate = int(((maxi2byte - i2bytesused) * 8)/(period - timeused)) if new_maxi2rate < self.Mini2Rate: new_maxi2rate = self.Mini2Rate else: - new_maxi2rate = self.Maxi2Rate + new_maxi2rate = self.Maxi2Rate * 1000 # Format template parameters for high bandwidth message params['class'] = "high bandwidth" params['bytes'] = format_bytes(usedi2bytes - self.i2bytes) params['maxrate'] = bwlimit.format_tc_rate(runningmaxi2rate) - params['limit'] = format_bytes(self.Maxi2KByte) + params['limit'] = format_bytes(self.Maxi2KByte * 1024) params['new_maxexemptrate'] = bwlimit.format_tc_rate(new_maxi2rate) if verbose: - print "%(slice)s %(class)s " \ - "%(bytes)s of %(limit)s (%(new_maxrate)s/s maxrate)" % params + logger.log("bwmon: %(slice)s %(class)s " \ + "%(bytes)s of %(limit)s (%(new_maxrate)s/s maxrate)" % params) # Cap high bandwidth burst rate if new_maxi2rate != runningmaxi2rate: message += template % params - print "%(slice)s %(class)s capped at %(new_maxexemptrate)s/s" % params + logger.log("bwmon: %(slice)s %(class)s capped at %(new_maxexemptrate)s/s" % params) # Apply parameters if new_maxrate != runningmaxrate or new_maxi2rate != runningmaxi2rate: @@ -258,8 +371,8 @@ class Slice: if message and self.emailed == False: subject = "pl_mom capped bandwidth of slice %(slice)s on %(hostname)s" % params if debug: - print subject - print message + (footer % params) + logger.log("bwmon: "+ subject) + logger.log("bwmon: "+ message + (footer % params)) else: self.emailed = True slicemail(self.name, subject, message + (footer % params)) @@ -268,45 +381,69 @@ def GetSlivers(data): # Defaults global datafile, \ period, \ - default_MaxRate, \ - default_Maxi2Rate, \ - default_MinRate, \ - default_MaxKByte,\ - default_ThreshKByte,\ + default_MaxRate, \ + default_Maxi2Rate, \ + default_MinRate, \ + default_MaxKByte,\ + default_ThreshKByte,\ default_Maxi2KByte,\ default_Threshi2KByte,\ - default_Share + default_Share,\ + verbose + verbose = True # All slices names = [] try: f = open(datafile, "r+") if verbose: - print "Loading %s" % datafile + logger.log("bwmon: Loading %s" % datafile) (version, slices) = pickle.load(f) f.close() # Check version of data file - if version != "$Id: bwmon.py,v 1.2 2007/02/07 18:12:02 faiyaza Exp $": - print "Not using old version '%s' data file %s" % (version, datafile) + if version != "$Id$": + logger.log("bwmon: Not using old version '%s' data file %s" % (version, datafile)) raise Exception except Exception: - version = "$Id: bwmon.py,v 1.2 2007/02/07 18:12:02 faiyaza Exp $" + version = "$Id$" slices = {} - # Get special slice IDs + # Get/set special slice IDs root_xid = bwlimit.get_xid("root") default_xid = bwlimit.get_xid("default") - live = [] - # Get actuall running values from tc. + if root_xid not in slices.keys(): + slices[root_xid] = Slice(root_xid, "root", data) + slices[root_xid].reset(0, 0, 0, 0, data) + + if default_xid not in slices.keys(): + slices[default_xid] = Slice(default_xid, "default", data) + slices[default_xid].reset(0, 0, 0, 0, data) + + live = {} + # Get running slivers. {xid: name} + for sliver in data['slivers']: + live[bwlimit.get_xid(sliver['name'])] = sliver['name'] + + # Setup new slices. + # live.xids - runing.xids = new.xids + newslicesxids = Set(live.keys()) - Set(slices.keys()) + for newslicexid in newslicesxids: + if newslicexid != None: + logger.log("bwmon: New Slice %s" % live[newslicexid]) + slices[newslicexid] = Slice(newslicexid, live[newslicexid], data) + slices[newslicexid].reset(0, 0, 0, 0, data) + else: + logger.log("bwmon Slice %s doesn't have xid. Must be delegated. Skipping." % live[newslicexid]) + # Get actual running values from tc. + # Update slice totals and bandwidth. for params in bwlimit.get(): (xid, share, minrate, maxrate, minexemptrate, maxexemptrate, - bytes, i2bytes) = params - live.append(xid) - + usedbytes, usedi2bytes) = params + # Ignore root and default buckets if xid == root_xid or xid == default_xid: continue @@ -325,40 +462,44 @@ def GetSlivers(data): if slices.has_key(xid): slice = slices[xid] if time.time() >= (slice.time + period) or \ - bytes < slice.bytes or i2bytes < slice.i2bytes: + usedbytes < slice.bytes or usedi2bytes < slice.i2bytes: # Reset to defaults every 24 hours or if it appears # that the byte counters have overflowed (or, more # likely, the node was restarted or the HTB buckets # were re-initialized). - slice.reset(maxrate, maxexemptrate, bytes, i2bytes, data) + slice.reset(maxrate, maxexemptrate, usedbytes, usedi2bytes, data) else: # Update byte counts - slice.update(maxrate, maxexemptrate, bytes, i2bytes, data) + slice.update(maxrate, maxexemptrate, usedbytes, usedi2bytes, data) else: + # Just in case. Probably (hopefully) this will never happen. # New slice, initialize state - slice = slices[xid] = Slice(xid, name, maxrate, maxexemptrate, bytes, i2bytes, data) + if verbose: + logger.log("bwmon: New Slice %s" % name) + slice = slices[xid] = Slice(xid, name, data) + slice.reset(maxrate, maxexemptrate, usedbytes, usedi2bytes, data) # Delete dead slices - dead = Set(slices.keys()) - Set(live) + dead = Set(slices.keys()) - Set(live.keys()) for xid in dead: + if xid == root_xid or xid == default_xid: + continue del slices[xid] bwlimit.off(xid) - print "Saving %s" % datafile + logger.log("bwmon: Saving %s" % datafile) f = open(datafile, "w") pickle.dump((version, slices), f) f.close() #def GetSlivers(data): -# for sliver in data['slivers']: -# if sliver.has_key('attributes'): -# print sliver -# for attribute in sliver['attributes']: -# if attribute['name'] == "KByteThresh": print attribute['value'] +# for sliver in data['slivers']: +# if sliver.has_key('attributes'): +# print sliver +# for attribute in sliver['attributes']: +# if attribute['name'] == "KByteThresh": print attribute['value'] def start(options, config): pass -if __name__ == '__main__': - main() diff --git a/delegate.py b/delegate.py index bb0942b..73a0743 100644 --- a/delegate.py +++ b/delegate.py @@ -10,7 +10,7 @@ class Delegate(accounts.Account): TYPE = 'delegate' @staticmethod - def create(name): + def create(name, vref = None): add_shell(Delegate.SHELL) logger.log_call('/usr/sbin/useradd', '-p', '*', '-s', Delegate.SHELL, name) diff --git a/net.py b/net.py index cd71fe9..9db7f73 100644 --- a/net.py +++ b/net.py @@ -3,8 +3,13 @@ import sioc import bwlimit import logger +import string -def GetSlivers(data): +def GetSlivers(plc, data): + InitNodeLimit(data) + InitI2(plc, data) + +def InitNodeLimit(data): # query running network interfaces devs = sioc.gifconf() ips = dict(zip(devs.values(), devs.keys())) @@ -14,16 +19,15 @@ def GetSlivers(data): # XXX Exempt Internet2 destinations from node bwlimits # bwlimit.exempt_init('Internet2', internet2_ips) - for network in data['networks']: # Get interface name preferably from MAC address, falling # back on IP address. - if macs.has_key(network['mac'].lower()): + if macs.has_key(network['mac']): dev = macs[network['mac'].lower()] elif ips.has_key(network['ip']): dev = ips[network['ip']] else: - logger.log('%s: no such interface with address %s/%s' % (self.name, network['ip'], network['mac'])) + logger.log('%s: no such interface with address %s/%s' % (network['hostname'], network['ip'], network['mac'])) continue # Get current node cap @@ -46,5 +50,14 @@ def GetSlivers(data): # some previously invalid sliver bwlimit is now valid # again, or vice-versa. +def InitI2(plc, data): + if "Internet2" in data['groups']: + logger.log("This is an Internet2 node. Setting rules.") + i2nodes = [] + i2nodeids = plc.GetNodeGroups(["Internet2"])[0]['node_ids'] + for node in plc.GetNodeNetworks({"node_id": i2nodeids}, ["ip"]): + i2nodes.append(node['ip']) + bwlimit.exempt_init('Internet2', i2nodes) + def start(options, config): pass diff --git a/nm.py b/nm.py index 6e56501..c4760fc 100644 --- a/nm.py +++ b/nm.py @@ -14,7 +14,7 @@ import logger import tools from config import Config -from plcapi import PLCAPI +from plcapi import PLCAPI savedargv = sys.argv[:] @@ -31,9 +31,13 @@ modules = [] def GetSlivers(plc): data = plc.GetSlivers() + # net needs access to API for i2 nodes. for module in modules: - callback = getattr(module, 'GetSlivers') - callback(data) + if module.__name__ == 'net': + module.GetSlivers(plc, data) + else: + callback = getattr(module, 'GetSlivers') + callback(data) def run(): try: @@ -51,7 +55,7 @@ def run(): print "Warning while writing PID file:", err # Load and start modules - for module in ['net', 'proper', 'conf_files', 'sm']: + for module in ['net', 'proper', 'conf_files', 'sm', 'bwmon']: try: m = __import__(module) m.start(options, config) diff --git a/setup.py b/setup.py index 824a604..333bf63 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ # Mark Huang # Copyright (C) 2006 The Trustees of Princeton University # -# $Id: setup.py,v 1.3 2006/11/27 22:42:48 mlhuang Exp $ +# $Id$ # from distutils.core import setup, Extension @@ -32,6 +32,7 @@ setup( 'sm', 'ticket', 'tools', + 'bwmon' ], scripts = [ 'forward_api_calls', diff --git a/sliver_vs.py b/sliver_vs.py index e4c438c..ce7a5cb 100644 --- a/sliver_vs.py +++ b/sliver_vs.py @@ -118,14 +118,14 @@ class Sliver_VS(accounts.Account, vserver.VServer): # N.B. net_*_rate are in kbps because of XML-RPC maxint # limitations, convert to bps which is what bwlimit.py expects. - net_limits = (self.rspec['net_min_rate'] * 1000, - self.rspec['net_max_rate'] * 1000, - self.rspec['net_i2_min_rate'] * 1000, - self.rspec['net_i2_max_rate'] * 1000, - self.rspec['net_share']) - logger.log('%s: setting net limits to %s bps' % (self.name, net_limits[:-1])) - logger.log('%s: setting net share to %d' % (self.name, net_limits[-1])) - self.set_bwlimit(*net_limits) +# net_limits = (self.rspec['net_min_rate'] * 1000, +# self.rspec['net_max_rate'] * 1000, +# self.rspec['net_i2_min_rate'] * 1000, +# self.rspec['net_i2_max_rate'] * 1000, +# self.rspec['net_share']) +# logger.log('%s: setting net limits to %s bps' % (self.name, net_limits[:-1])) +# logger.log('%s: setting net share to %d' % (self.name, net_limits[-1])) +# self.set_bwlimit(*net_limits) cpu_min = self.rspec['cpu_min'] cpu_share = self.rspec['cpu_share'] diff --git a/sm.py b/sm.py index 956a11e..680120c 100644 --- a/sm.py +++ b/sm.py @@ -57,6 +57,17 @@ def GetSlivers(data, fullupdate=True): if network['is_primary'] and network['bwlimit'] is not None: DEFAULT_ALLOCATION['net_max_rate'] = network['bwlimit'] / 1000 +### Emulab-specific hack begins here + emulabdelegate = { + 'instantiation': 'plc-instantiated', + 'keys': '''ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA5Rimz6osRvlAUcaxe0YNfGsLL4XYBN6H30V3l/0alZOSXbGOgWNdEEdohwbh9E8oYgnpdEs41215UFHpj7EiRudu8Nm9mBI51ARHA6qF6RN+hQxMCB/Pxy08jDDBOGPefINq3VI2DRzxL1QyiTX0jESovrJzHGLxFTB3Zs+Y6CgmXcnI9i9t/zVq6XUAeUWeeXA9ADrKJdav0SxcWSg+B6F1uUcfUd5AHg7RoaccTldy146iF8xvnZw0CfGRCq2+95AU9rbMYS6Vid8Sm+NS+VLaAyJaslzfW+CAVBcywCOlQNbLuvNmL82exzgtl6fVzutRFYLlFDwEM2D2yvg4BQ== root@boss.emulab.net''', + 'name': 'utah_elab_delegate', + 'timestamp': data['timestamp'], + 'type': 'delegate', + 'vref': None + } + database.db.deliver_record(emulabdelegate) +### Emulab-specific hack ends here for sliver in data['slivers']: rec = sliver.copy() rec.setdefault('timestamp', data['timestamp'])