-Copyright 2008 Princeton University
+Copyright 2009 Princeton University
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
"""Functionality common to all account classes.
-Each subclass of Account must provide five methods: create() and
-destroy(), which are static; configure(), start(), and stop(), which
-are not. configure(), which takes a record as its only argument, does
+Each subclass of Account must provide 6 methods: create() and
+destroy(), which are static; configure(), is_running(), start(), and stop(),
+which are not. configure() takes a record as its only argument, and does
things like set up ssh keys. In addition, an Account subclass must
provide static member variables SHELL, which contains the unique shell
that it uses; and TYPE, a string that is used by the account creation
# private account name -> worker object association and associated lock
name_worker_lock = threading.Lock()
-# dict of account_name: <Worker Object>
name_worker = {}
def allpwents():
"""Return the worker object for a particular username. If no such object exists, create it first."""
name_worker_lock.acquire()
try:
- if name not in name_worker:
- logger.verbose("Accounts:get(%s) new Worker" % name)
- name_worker[name] = Worker(name)
+ if name not in name_worker: name_worker[name] = Worker(name)
return name_worker[name]
finally: name_worker_lock.release()
def stop(self): self._acct.stop()
def is_running(self):
- if self._acct.is_running():
+ if (self._acct != None) and self._acct.is_running():
status = True
else:
status = False
def allOff():
- # Get/set special slice IDs
+ """
+ Turn off all slice HTBs
+ """
+ # Get/set special slice IDs
root_xid = bwlimit.get_xid("root")
default_xid = bwlimit.get_xid("default")
kernelhtbs = gethtbs(root_xid, default_xid)
lock = threading.Event()
def run():
"""
- When run as a thread, wait for event, lock db, deep copy it, release it,
- run bwmon.GetSlivers(), then go back to waiting.
- """
+ When run as a thread, wait for event, lock db, deep copy it, release it,
+ run bwmon.GetSlivers(), then go back to waiting.
+ """
logger.log("bwmon: Thread started", 2)
while True:
lock.wait()
nmdbcopy = copy.deepcopy(database.db)
database.db_lock.release()
try:
- if getDefaults(nmdbcopy): sync(nmdbcopy)
- else: logger.log("bwmon: DISABLED.")
+ if getDefaults(nmdbcopy) and len(bwlimit.tc("class show dev eth0")) > 0:
+ # class show to check if net:InitNodeLimit:bwlimit.init has run.
+ sync(nmdbcopy)
+ else: logger.log("bwmon: BW limits DISABLED.")
except: logger.log_exc()
lock.clear()
#
"""network configuration"""
-import sioc
-import bwlimit
-import logger
-import string
-import iptables
-import os
-import plnet
-
-def GetSlivers(plc, data):
- InitInterfaces(plc, data)
- InitNodeLimit(data)
- InitI2(plc, data)
+# system provided modules
+import os, string, time, socket
+
+# PlanetLab system modules
+import sioc, plnet
+
+# local modules
+import bwlimit, logger, iptables
+
+def GetSlivers(plc, data, config):
+ logger.verbose("net:GetSlivers called.")
+ InitInterfaces(plc, data) # writes sysconfig files.
+ if 'OVERRIDES' in dir(config):
+ if config.OVERRIDES.get('net_max_rate') == '-1':
+ logger.log("net: Slice and node BW Limits disabled.")
+ if len(bwlimit.tc("class show dev eth0")):
+ logger.verbose("*** DISABLING NODE BW LIMITS ***")
+ bwlimit.stop()
+ else:
+ InitNodeLimit(data)
+ InitI2(plc, data)
+ else:
+ InitNodeLimit(data)
+ InitI2(plc, data)
InitNAT(plc, data)
+
def InitNodeLimit(data):
# query running network interfaces
devs = sioc.gifconf()
modules = []
-def GetSlivers(plc):
+def GetSlivers(plc, config):
'''Run call backs defined in modules'''
try:
logger.log("Syncing w/ PLC")
data = plc.GetSlivers()
+ getPLCDefaults(data, config)
+ if (options.verbose): logger.log_slivers(data)
except:
logger.log_exc()
# XXX So some modules can at least boostrap.
+ logger.log("nm: Can't contact PLC to GetSlivers(). Continuing.")
data = {}
- logger.log_slivers(data)
- # Set i2 ip list for nodes in I2 nodegroup.
- try: net.GetSlivers(plc, data)
+ # Set i2 ip list for nodes in I2 nodegroup
+ # and init network interfaces (unless overridden)
+ try: net.GetSlivers(plc, data, config) # TODO - num of args needs to be unified across mods.
except: logger.log_exc()
# All other callback modules
for module in modules:
callback(data)
except: logger.log_exc()
+
+def getPLCDefaults(data, config):
+ '''
+ Get PLC wide defaults from _default system slice. Adds them to config class.
+ '''
+ for slice in data.get('slivers'):
+ if slice['name'] == config.PLC_SLICE_PREFIX+"_default":
+ attr_dict = {}
+ for attr in slice.get('attributes'): attr_dict[attr['name']] = attr['value']
+ if len(attr_dict):
+ logger.verbose("Found default slice overrides.\n %s" % attr_dict)
+ config.OVERRIDES = attr_dict
+ return
+ if 'OVERRIDES' in dir(config): del config.OVERRIDES
+
+
def run():
try:
if options.daemon: tools.daemon()
while True:
# Main NM Loop
logger.verbose('mainloop - nm:getSlivers - period=%d random=%d'%(iperiod,irandom))
- GetSlivers(plc)
+ GetSlivers(plc, config)
delay=iperiod + random.randrange(0,irandom)
logger.verbose('mainloop - sleeping for %d s'%delay)
time.sleep(delay)
'bwmon',
'conf_files',
'config',
- 'curlwrapper',
'controller',
+ 'curlwrapper',
'database',
'iptables',
'logger',
keys = rec.pop('keys')
rec.setdefault('keys', '\n'.join([key_struct['key'] for key_struct in keys]))
+ ## 'Type' isn't returned by GetSlivers() for whatever reason. We're overloading
+ ## instantiation here, but i suppose its the ssame thing when you think about it. -FA
+ # Handle nm controller here
if rec['instantiation'].lower() == 'nm-controller':
rec.setdefault('type', attr_dict.get('type', 'controller.Controller'))
else:
except (KeyError, ValueError): amt = default_amt
rspec[resname] = amt
+ # add in sysctl attributes into the rspec
+ for key in attr_dict.keys():
+ if key.find("sysctl.") == 0:
+ rspec[key] = attr_dict[key]
+
database.db.deliver_record(rec)
if fullupdate: database.db.set_min_timestamp(data['timestamp'])
# slivers are created here.