Merge branch 'master' of ssh://git.planet-lab.org/git/nodemanager
authorAndy Bavier <acb@cs.princeton.edu>
Wed, 24 Oct 2012 20:38:58 +0000 (15:38 -0500)
committerAndy Bavier <acb@cs.princeton.edu>
Wed, 24 Oct 2012 20:38:58 +0000 (15:38 -0500)
nodemanager-lxc.spec
plugins/interfaces.py [new file with mode: 0644]
sliver_libvirt.py
sliver_lxc.py

index 847cb20..7d82875 100644 (file)
@@ -32,6 +32,8 @@ Requires: python-inotify
 Requires: nodemanager-lib
 # the lxc-specific tools for using slice images
 Requires: lxc-sliceimage
+Requires: openvswitch
+Requires: sliceimage-lxc >= 5.1-3
 
 %description
 nodemanager-lxc provides the lxc code for the PlanetLab Node Manager.
diff --git a/plugins/interfaces.py b/plugins/interfaces.py
new file mode 100644 (file)
index 0000000..51c7cf2
--- /dev/null
@@ -0,0 +1,83 @@
+"""
+Configure interfaces inside a container by pulling down files via URL.
+"""
+
+import logger
+import os
+import curlwrapper
+import xmlrpclib
+try:
+    from hashlib import sha1 as sha
+except ImportError:
+    from sha import sha
+import subprocess
+
+def checksum(path):
+    try:
+        f = open(path)
+        try: return sha(f.read()).digest()
+        finally: f.close()
+    except IOError: 
+        return None
+
+def start():
+    logger.log("interfaces: plugin starting up...")
+
+def GetSlivers(data, config=None, plc=None):
+
+    if 'slivers' not in data:
+        logger.log_missing_data("interfaces.GetSlivers",'slivers')
+        return
+
+    for sliver in data['slivers']:
+        slicename = sliver['name']
+        for tag in sliver['attributes']:
+            if tag['tagname'] == 'interface':
+                mydict = eval(tag['value'])
+                contents=""
+                # First look for filename/url combination for custom config files
+                if 'filename' in mydict and 'url' in mydict:
+                    dest = "/vservers/%s/%s" % (slicename, mydict['filename'])
+                    url = mydict['url']
+                    try:
+                        contents = curlwrapper.retrieve(url)
+                    except xmlrpclib.ProtocolError,e:
+                        logger.log('interfaces (%s): failed to retrieve %s' % (slicename, url))
+                        continue
+                else:
+                    # Otherwise generate /etc/sysconfig/network-scripts/ifcfg-<device>
+                    try:
+                        dest = "/vservers/%s/etc/sysconfig/network-scripts/ifcfg-%s" % (slicename, mydict['DEVICE'])
+                    except:
+                        logger.log('interfaces (%s): no DEVICE specified' % slicename)
+                        continue
+
+                    for key, value in mydict.items():
+                        if key in ['bridge']: 
+                            continue
+                        contents += '%s="%s"\n' % (key, value)
+
+                if sha(contents).digest() == checksum(dest):
+                    logger.log('interfaces (%s): no changes to %s' % (slicename, dest))
+                    continue
+
+                logger.log('interfaces (%s): installing file %s' % (slicename, dest))
+                try: 
+                    os.makedirs(os.path.dirname(dest))
+                except OSError: 
+                    pass
+
+                try:
+                    f = open (dest, "w")
+                    f.write(contents)
+                    f.close()
+                except:
+                    logger.log('interfaces (%s): error writing file %s' % (slicename, dest))
+                    continue
+
+                try:
+                    subprocess.check_call(['/usr/sbin/lxcsu', slicename, '/sbin/service', 
+                                           'network', 'restart'])
+                except:
+                    logger.log('interfaces (%s): error restarting network service' % slicename)
+                    
index 6f4cce1..778eb10 100644 (file)
@@ -163,3 +163,28 @@ class Sliver_Libvirt(Account):
         # Call the upper configure method (ssh keys...)
         Account.configure(self, rec)
 
+    # A placeholder until we get true VirtualInterface objects
+    @staticmethod
+    def get_interfaces_xml(rec):
+        xml = """
+    <interface type='network'>
+      <source network='default'/>
+    </interface>
+"""
+        try:
+            tags = rec['rspec']['tags']
+            if 'interface' in tags:
+                interface = eval(tags['interface'])
+                if 'bridge' in interface:
+                    xml = """
+    <interface type='bridge'>
+      <source bridge='%s'/>
+      <virtualport type='openvswitch'/>
+    </interface>
+""" % interface['bridge']
+                    logger.log('sliver_libvirty.py: interface XML is: %s' % xml)
+        except:
+            logger.log('sliver_libvirt.py: ERROR parsing "interface" tag for slice %s' % rec['name'])
+            logger.log('sliver_libvirt.py: tag value: %s' % tags['interface'])
+
+        return xml
index d3e077f..f2521a3 100644 (file)
@@ -146,10 +146,13 @@ class Sliver_LXC(Sliver_Libvirt, Initscript):
         else:
             logger.log("Cannot find XML template %s"%template_filename_sliceimage)
             return
+
+        interfaces = Sliver_Libvirt.get_interfaces_xml(rec)
+
         try:
             with open(template_filename) as f:
                 template = Template(f.read())
-                xml  = template.substitute(name=name, xid=xid)
+                xml  = template.substitute(name=name, interfaces=interfaces)
         except IOError:
             logger.log('Failed to parse or use XML template file %s'%template_filename)
             return