data = {}
# Invoke GetSlivers() functions from the callback modules
for module in modules:
-# logger.log('trigerring GetSlivers callback for module %s'%module.__name__)
+ logger.verbose('trigerring GetSlivers callback for module %s'%module.__name__)
try:
callback = getattr(module, 'GetSlivers')
callback(data, config, plc)
return getattr(m1,'priority',default_priority) - getattr(m2,'priority',default_priority)
modules.sort(sort_module_priority)
- logger.verbose('modules priorities and order:')
- for module in modules: logger.verbose ('%s: %s'%(getattr(module,'priority',default_priority),module.__name__))
+ logger.log('ordered modules:')
+ for module in modules: logger.log ('%s: %s'%(getattr(module,'priority',default_priority),module.__name__))
# Load /etc/planetlab/session
if os.path.exists(options.session):
--- /dev/null
+#
+# $Id$
+# $URL$
+#
+# NodeManager plugin - first step of handling omf_controlled slices
+
+"""
+Overwrites the 'resctl' tag of slivers controlled by OMF so sm.py does the right thing
+"""
+
+import subprocess
+
+import tools
+import logger
+
+priority = 11
+
+### xxx this should not be version-dependent
+service_name='omf-resctl-5.3'
+
+def start(options, conf):
+ logger.log("omf_resctl: plugin starting up...")
+
+def GetSlivers(data, conf = None, plc = None):
+ if 'accounts' not in data:
+ logger.log_missing_data("omf_resctl.GetSlivers",'accounts')
+ return
+
+ try:
+ xmpp_server=data['xmpp']['server']
+ except:
+ # disabled feature - bailing out
+ # xxx might need to clean up more deeply..
+ return
+
+ for sliver in data['slivers']:
+ name=sliver['name']
+ for chunk in sliver['attributes']:
+ if chunk['tagname']=='omf_control':
+ # filenames
+ yaml="/vservers/%s/etc/omf-resctl/omf-resctl.yaml"%name
+ template="%s.in"%yaml
+ # read template and replace
+ template=file(template).read()
+ yaml_contents=template\
+ .replace('@XMPP_SERVER@',xmpp_server)\
+ .replace('@NODE_HRN@','default')\
+ .replace('@SLICE_NAME@',name)
+ changes=tools.replace_file_with_string(yaml,yaml_contents)
+ if changes:
+ sp=subprocess.Popen(['vserver',name,'exec','service',service_name,'restart'],
+ stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
+ (output,retcod)=sp.communicate()
+ logger.log("omf_resctl: %s: restarted resource controller (retcod=%r)"%(name,retcod))
+ logger.log("omf_resctl: got output\n%s"%output)
+ else:
+ logger.log("omf_resctl: %s: omf_control'ed sliver has no change" % name)
--- /dev/null
+#
+# $Id$
+# $URL$
+#
+# NodeManager plugin - first step of handling omf_controlled slices
+
+"""
+Overwrites the 'vref' tag of slivers controlled by OMF so sm.py does the right thing
+Needs to be done the 'sm' module kicks in
+"""
+
+import logger
+
+# do this early, before step 10
+priority = 4
+
+def start(options, conf):
+ logger.log("omf_vref: plugin starting up...")
+
+def GetSlivers(data, conf = None, plc = None):
+ if 'accounts' not in data:
+ logger.log_missing_data("omf_vref.GetSlivers",'accounts')
+ return
+
+ for sliver in data['slivers']:
+ name=sliver['name']
+ for chunk in sliver['attributes']:
+ if chunk['tagname']=='omf_control':
+ sliver['vref']='omf'
+ logger.log('omf_vref: %s now has vref==omf' % name)
priority = 3
def start(options, conf):
- logger.log("personkeys: plugin starting up...")
+ logger.log("specialaccounts: plugin starting up...")
def GetSlivers(data, conf = None, plc = None):
if 'accounts' not in data:
if not os.access(dot_ssh, os.F_OK): os.mkdir(dot_ssh)
auth_keys = os.path.join(dot_ssh,'authorized_keys')
- logger.log("specialaccounts: new keys = %s" % auth_keys)
- fd, fname = tempfile.mkstemp('','authorized_keys',dot_ssh)
+ # catenate all keys in string, add newlines just in case (looks like keys already have this, but)
+ auth_keys_contents = '\n'.join(new_keys)+'\n'
- for key in new_keys:
- os.write(fd,key)
- os.write(fd,'\n')
-
- os.close(fd)
- if os.path.exists(auth_keys): os.unlink(auth_keys)
- os.rename(fname, auth_keys)
-
- # set permissions properly
+ changes = tools.replace_file_with_string(auth_keys,auth_keys_contents)
+ if changes:
+ logger.log("specialaccounts: keys file changed: %s" % auth_keys)
+
+ # always set permissions properly
os.chmod(dot_ssh, 0700)
os.chown(dot_ssh, uid,gid)
os.chmod(auth_keys, 0600)
os.chown(auth_keys, uid,gid)
- logger.log('specialacounts: installed ssh keys for %s' % name)
+ logger.log('specialaccounts: installed ssh keys for %s' % name)
"""A few things that didn't seem to fit anywhere else."""
-import cPickle
-import errno
import os
import pwd
import tempfile
-import threading
import fcntl
-import commands
+import errno
+import threading
+import subprocess
+
import logger
PID_FILE = '/var/run/nm.pid'
+####################
def get_default_if():
interface = get_if_from_hwaddr(get_hwaddr_from_plnode())
if not interface: interface = "eth0"
if dev_hwaddr == hwaddr: return dev
return None
+####################
+# daemonizing
def as_daemon_thread(run):
"""Call function <run> with no arguments in its own thread."""
thr = threading.Thread(target=run)
os._exit(0)
else: os.waitpid(child_pid, 0)
+####################
+# manage files
def pid_file():
"""We use a pid file to ensure that only one copy of NM is running at a given time. If successful, this function will write a pid file containing the pid of the current process. The return value is the pid of the other running process, or None otherwise."""
other_pid = None
finally: f.close()
return temporary_filename
+# replace a target file with a new contents - checks for changes
+# return True if a change occurred, in which case
+# chown/chmod settings should be taken care of
+def replace_file_with_string (target, new_contents):
+ try:
+ current=file(target).read()
+ except:
+ current=""
+ # xxx if verbose, report diffs...
+ if current==new_contents:
+ return False
+ # overwrite target file
+ f=file(target,'w')
+ f.write(new_contents)
+ f.close()
+ return True
+
+# not needed yet - should that unlink the new file ?
+#def replace_file_with_file (target, new):
+# return replace_file_with_string (target, file(new).read())
+
+####################
# utilities functions to get (cached) information from the node
# get node_id from /etc/planetlab/node_id and cache it
def root_context_arch():
global _root_context_arch
if not _root_context_arch:
- _root_context_arch=commands.getoutput("uname -i")
+ sp=subprocess.Popen(["uname","-i"],stdout=subprocess.PIPE)
+ (_root_context_arch,_)=sp.communicate()
+ _root_context_arch=_root_context_arch.strip()
return _root_context_arch
+####################
class NMLock:
def __init__(self, file):
logger.log("tools: Lock %s initialized." % file, 2)