Use pyplnet.
authorDaniel Hokka Zakrisson <dhokka@cs.princeton.edu>
Wed, 3 Dec 2008 16:32:52 +0000 (16:32 +0000)
committerDaniel Hokka Zakrisson <dhokka@cs.princeton.edu>
Wed, 3 Dec 2008 16:32:52 +0000 (16:32 +0000)
NodeManager.spec
modprobe.py [deleted file]
net.py
setup.py
sioc.c [deleted file]

index 093eba6..fc5ef93 100644 (file)
@@ -25,6 +25,8 @@ Packager: PlanetLab Central <support@planet-lab.org>
 Distribution: PlanetLab %{plrelease}
 URL: %(echo %{url} | cut -d ' ' -f 2)
 
+BuildArch: noarch
+
 # Old Node Manager
 Obsoletes: sidewinder, sidewinder-common
 
@@ -44,6 +46,9 @@ Requires: curl
 # Uses function decorators
 Requires: python >= 2.4
 
+# sioc/plnet
+Requires: pyplnet = 4.2
+
 %description
 The PlanetLab Node Manager manages all aspects of PlanetLab node and
 slice management once the node has been initialized and configured by
@@ -95,11 +100,7 @@ rm -rf $RPM_BUILD_ROOT
 
 %files
 %defattr(-,root,root,-)
-%doc
-%dir %{_datadir}/NodeManager
-%dir %{_datadir}/NodeManager/plugins
-%{_datadir}/NodeManager/*
-%{_datadir}/NodeManager/plugins/*
+%{_datadir}/NodeManager/
 %{_bindir}/forward_api_calls
 %{_initrddir}/nm
 %{_initrddir}/conf_files
diff --git a/modprobe.py b/modprobe.py
deleted file mode 100644 (file)
index d7fa2e3..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-#
-# $Id$
-#
-
-"""Modprobe is a utility to read/modify/write /etc/modprobe.conf"""
-
-import os
-
-class Modprobe():
-    def __init__(self,filename="/etc/modprobe.conf"):
-        self.conffile = {}
-        self.origconffile = {}
-        for keyword in ("alias","options","install","remove","blacklist","MODULES"):
-            self.conffile[keyword]={}
-        self.filename = filename
-
-    def input(self,filename=None):
-        if filename==None: filename=self.filename
-        fb = file(filename,"r")
-        for line in fb.readlines():
-            parts = line.split()
-            command = parts[0].lower()
-
-            table = self.conffile.get(command,None)
-            if table == None:
-                print "WARNING: command %s not recognize. Ignoring!" % command
-                continue
-
-            if command == "alias":
-                wildcard=parts[1]
-                modulename=parts[2]
-                self.aliasset(wildcard,modulename)
-                options=''
-                if len(parts)>3:
-                    options=" ".join(parts[3:])
-                    self.optionsset(modulename,options)
-                    self.conffile['MODULES']={}
-                self.conffile['MODULES'][modulename]=options
-            else:
-                modulename=parts[1]
-                rest=" ".join(parts[2:])
-                self._set(command,modulename,rest)
-                if command == "options":
-                    self.conffile['MODULES'][modulename]=rest
-
-        self.origconffile = self.conffile.copy()
-                
-    def _get(self,command,key):
-        return self.conffile[command].get(key,None)
-
-    def _set(self,command,key,value):
-        self.conffile[command][key]=value
-
-    def aliasget(self,key):
-        return self._get('alias',key)
-
-    def optionsget(self,key):
-        return self._get('options',key)
-
-    def aliasset(self,key,value):
-        self._set("alias",key,value)
-
-    def optionsset(self,key,value):
-        self._set("options",key,value)
-        
-    def _comparefiles(self,a,b):
-        try:
-            if not os.path.exists(a): return False
-            fb = open(a)
-            buf_a = fb.read()
-            fb.close()
-
-            if not os.path.exists(b): return False
-            fb = open(b)
-            buf_b = fb.read()
-            fb.close()
-
-            return buf_a == buf_b
-        except IOError, e:
-            return False
-
-    def output(self,filename="/etc/modprobe.conf",program="NodeManager"):
-        tmpnam = os.tmpnam()
-        fb = file(tmpnam,"w")
-        fb.write("# Written out by %s\n" % program)
-
-        for command in ("alias","options","install","remove","blacklist"):
-            table = self.conffile[command]
-            keys = table.keys()
-            keys.sort()
-            for k in keys:
-                v = table[k]
-                fb.write("%s %s %s\n" % (command,k,v))
-
-        fb.close()
-        if not self._comparefiles(tmpnam,filename):
-            os.rename(tmpnam,filename)
-            os.chmod(filename,0644)
-            return True
-        else:
-            return False
-
-    def probe(self,name):
-        o = os.popen("/sbin/modprobe %s" % name)
-        o.close()
-
-    def checkmodules(self):
-        syspath="/sys/module"
-        modules = os.listdir(syspath)
-        for module in modules:
-            path="%/%s/parameters"%(syspath,module)
-            if os.path.exists(path):
-                ps=os.listdir(path)
-                parameters={}
-                for p in ps:
-                    fb = file("%s/%s"%(path,p),"r")
-                    parameters[p]=fb.readline()
-                    fb.close()
-         
-if __name__ == '__main__':
-    import sys
-    if len(sys.argv)>1:
-        m = Modprobe(sys.argv[1])
-    else:
-        m = Modprobe()
-
-    m.input()
-    m.aliasset("bond0","bonding")
-    m.optionsset("bond0","miimon=100")
-    m.output("/tmp/x")
diff --git a/net.py b/net.py
index 873f4db..2e7f6eb 100644 (file)
--- a/net.py
+++ b/net.py
@@ -5,10 +5,13 @@
 """network configuration"""
 
 # system provided modules
-import os, string, time, socket, modprobe
+import os, string, time, socket
+
+# PlanetLab system modules
+import sioc, plnet
 
 # local modules
-import sioc, bwlimit, logger, iptables
+import bwlimit, logger, iptables
 
 def GetSlivers(plc, data):
     InitInterfaces(plc, data)
@@ -138,279 +141,7 @@ def InitNAT(plc, data):
 
 def InitInterfaces(plc, data):
     if not 'networks' in data: return
-
-    sysconfig = "/etc/sysconfig/network-scripts"
-
-    # query running network interfaces
-    devs = sioc.gifconf()
-    ips = dict(zip(devs.values(), devs.keys()))
-    macs = {}
-    for dev in devs:
-        macs[sioc.gifhwaddr(dev).lower()] = dev
-
-    # assume data['networks'] contains this node's NodeNetworks
-    interfaces = {}
-    interface = 1
-    hostname = data.get('hostname',socket.gethostname())
-    networks = data['networks']
-    failedToGetSettings = False
-    for network in networks:
-       logger.verbose('net:InitInterfaces interface %d: %s'%(interface,network))
-       logger.verbose('net:InitInterfaces macs = %s' % macs)
-        logger.verbose('net:InitInterfaces ips = %s' % ips)
-        # Get interface name preferably from MAC address, falling back
-        # on IP address.
-        hwaddr=network['mac']
-        if hwaddr <> None: hwaddr=hwaddr.lower()
-        if hwaddr in macs:
-            orig_ifname = macs[hwaddr]
-        elif network['ip'] in ips:
-            orig_ifname = ips[network['ip']]
-        else:
-            orig_ifname = None
-
-       if orig_ifname:
-                       logger.verbose('net:InitInterfaces orig_ifname = %s' % orig_ifname)
-       
-        inter = {}
-        inter['ONBOOT']='yes'
-        inter['USERCTL']='no'
-        if network['mac']:
-            inter['HWADDR'] = network['mac']
-
-        if network['method'] == "static":
-            inter['BOOTPROTO'] = "static"
-            inter['IPADDR'] = network['ip']
-            inter['NETMASK'] = network['netmask']
-
-        elif network['method'] == "dhcp":
-            inter['BOOTPROTO'] = "dhcp"
-            if network['hostname']:
-                inter['DHCP_HOSTNAME'] = network['hostname']
-            else:
-                inter['DHCP_HOSTNAME'] = hostname 
-            if not network['is_primary']:
-                inter['DHCLIENTARGS'] = "-R subnet-mask"
-
-        if len(network['nodenetwork_setting_ids']) > 0:
-            try:
-                settings = plc.GetNodeNetworkSettings({'nodenetwork_setting_id':
-                                                       network['nodenetwork_setting_ids']})
-            except:
-                logger.log("net:InitInterfaces FATAL: failed call GetNodeNetworkSettings({'nodenetwork_setting_id':{%s})"% \
-                           network['nodenetwork_setting_ids'])
-                failedToGetSettings = True
-                continue # on to the next network
-
-            for setting in settings:
-                # to explicitly set interface name
-                settingname = setting['name'].upper()
-                if settingname in ('IFNAME','ALIAS','CFGOPTIONS','DRIVER'):
-                    inter[settingname]=setting['value']
-                else:
-                    logger.log("net:InitInterfaces WARNING: ignored setting named %s"%setting['name'])
-
-        # support aliases to interfaces either by name or HWADDR
-        if 'ALIAS' in inter:
-            if 'HWADDR' in inter:
-                hwaddr = inter['HWADDR'].lower()
-                del inter['HWADDR']
-                if hwaddr in macs:
-                    hwifname = macs[hwaddr]
-                    if ('IFNAME' in inter) and inter['IFNAME'] <> hwifname:
-                        logger.log("net:InitInterfaces WARNING: alias ifname (%s) and hwaddr ifname (%s) do not match"%\
-                                       (inter['IFNAME'],hwifname))
-                        inter['IFNAME'] = hwifname
-                else:
-                    logger.log('net:InitInterfaces WARNING: mac addr %s for alias not found' %(hwaddr,alias))
-
-            if 'IFNAME' in inter:
-                # stupid RH /etc/sysconfig/network-scripts/ifup-aliases:new_interface()
-                # checks if the "$DEVNUM" only consists of '^[0-9A-Za-z_]*$'. Need to make
-                # our aliases compliant.
-                parts = inter['ALIAS'].split('_')
-                isValid=True
-                for part in parts:
-                    isValid=isValid and part.isalnum()
-
-                if isValid:
-                    interfaces["%s:%s" % (inter['IFNAME'],inter['ALIAS'])] = inter 
-                else:
-                    logger.log("net:InitInterfaces WARNING: interface alias (%s) not a valid string for RH ifup-aliases"% inter['ALIAS'])
-            else:
-                logger.log("net:InitInterfaces WARNING: interface alias (%s) not matched to an interface"% inter['ALIAS'])
-            interface -= 1
-        else:
-            if ('IFNAME' not in inter) and not orig_ifname:
-                ifname="eth%d" % (interface-1)
-                # should check if $ifname is an eth already defines
-                if os.path.exists("%s/ifcfg-%s"%(sysconfig,ifname)):
-                    logger.log("net:InitInterfaces WARNING: possibly blowing away %s configuration"%ifname)
-            else:
-               if ('IFNAME' not in inter) and orig_ifname:
-                    ifname = orig_ifname
-                else:
-                    ifname = inter['IFNAME']
-                interface -= 1
-            interfaces[ifname] = inter
-                
-    m = modprobe.Modprobe()
-    m.input("/etc/modprobe.conf")
-    for (dev, inter) in interfaces.iteritems():
-        # get the driver string "moduleName option1=a option2=b"
-        driver=inter.get('DRIVER','')
-        if driver <> '':
-            driver=driver.split()
-            kernelmodule=driver[0]
-            m.aliasset(dev,kernelmodule)
-            options=" ".join(driver[1:])
-            if options <> '':
-                m.optionsset(dev,options)
-    m.output("/etc/modprobe.conf")
-
-    # clean up after any ifcfg-$dev script that's no longer listed as
-    # part of the NodeNetworks associated with this node
-
-    # list all network-scripts
-    files = os.listdir(sysconfig)
-
-    # filter out the ifcfg-* files
-    ifcfgs=[]
-    for f in files:
-        if f.find("ifcfg-") == 0:
-            ifcfgs.append(f)
-
-    # remove loopback (lo) from ifcfgs list
-    lo = "ifcfg-lo"
-    if lo in ifcfgs: ifcfgs.remove(lo)
-
-    # remove known devices from icfgs list
-    for (dev, inter) in interfaces.iteritems():
-        ifcfg = 'ifcfg-'+dev
-        if ifcfg in ifcfgs: ifcfgs.remove(ifcfg)
-
-    # delete the remaining ifcfgs from 
-    deletedSomething = False
-
-    if not failedToGetSettings:
-        for ifcfg in ifcfgs:
-            dev = ifcfg[len('ifcfg-'):]
-            path = "%s/ifcfg-%s" % (sysconfig,dev)
-            logger.verbose("net:InitInterfaces removing %s %s"%(dev,path))
-            ifdown = os.popen("/sbin/ifdown %s" % dev)
-            ifdown.close()
-            deletedSomething=True
-            os.unlink(path)
-
-    # wait a bit for the one or more ifdowns to have taken effect
-    if deletedSomething:
-        time.sleep(2)
-
-    # Process ifcg-$dev changes / additions
-    newdevs = []
-    for (dev, inter) in interfaces.iteritems():
-        tmpnam = os.tmpnam()
-        f = file(tmpnam, "w")
-        f.write("# Autogenerated by NodeManager/net.py.... do not edit!\n")
-        if 'DRIVER' in inter:
-            f.write("# using %s driver for device %s\n" % (inter['DRIVER'],dev))
-        f.write('DEVICE="%s"\n' % dev)
-        
-        # print the configuration values
-        for (key, val) in inter.iteritems():
-            if key not in ('IFNAME','ALIAS','CFGOPTIONS','DRIVER'):
-                f.write('%s="%s"\n' % (key, val))
-
-        # print the configuration specific option values (if any)
-        if 'CFGOPTIONS' in inter:
-            cfgoptions = inter['CFGOPTIONS']
-            f.write('#CFGOPTIONS are %s\n' % cfgoptions)
-            for cfgoption in cfgoptions.split():
-                key,val = cfgoption.split('=')
-                key=key.strip()
-                key=key.upper()
-                val=val.strip()
-                f.write('%s="%s"\n' % (key,val))
-        f.close()
-
-        # compare whether two files are the same
-        def comparefiles(a,b):
-            try:
-               logger.verbose("net:InitInterfaces comparing %s with %s" % (a,b))
-                if not os.path.exists(a): return False
-                fb = open(a)
-                buf_a = fb.read()
-                fb.close()
-
-                if not os.path.exists(b): return False
-                fb = open(b)
-                buf_b = fb.read()
-                fb.close()
-
-                return buf_a == buf_b
-            except IOError, e:
-                return False
-
-        path = "%s/ifcfg-%s" % (sysconfig,dev)
-        if not os.path.exists(path):
-            logger.verbose('net:InitInterfaces adding configuration for %s' % dev)
-            # add ifcfg-$dev configuration file
-            os.rename(tmpnam,path)
-            os.chmod(path,0644)
-            newdevs.append(dev)
-            
-        elif not comparefiles(tmpnam,path):
-            logger.verbose('net:InitInterfaces Configuration change for %s' % dev)
-            logger.verbose('net:InitInterfaces ifdown %s' % dev)
-            # invoke ifdown for the old configuration
-            p = os.popen("/sbin/ifdown %s" % dev)
-            p.close()
-            # wait a few secs for ifdown to complete
-            time.sleep(2)
-
-            logger.log('replacing configuration for %s' % dev)
-            # replace ifcfg-$dev configuration file
-            os.rename(tmpnam,path)
-            os.chmod(path,0644)
-            newdevs.append(dev)
-        else:
-            # tmpnam & path are identical
-            os.unlink(tmpnam)
-
-    for dev in newdevs:
-        cfgvariables = {}
-        fb = file("%s/ifcfg-%s"%(sysconfig,dev),"r")
-        for line in fb.readlines():
-            parts = line.split()
-            if parts[0][0]=="#":continue
-            if parts[0].find('='):
-                name,value = parts[0].split('=')
-                # clean up name & value
-                name = name.strip()
-                value = value.strip()
-                value = value.strip("'")
-                value = value.strip('"')
-                cfgvariables[name]=value
-        fb.close()
-
-        def getvar(name):
-            if name in cfgvariables:
-                value=cfgvariables[name]
-                value = value.lower()
-                return value
-            return ''
-
-        # skip over device configs with ONBOOT=no
-        if getvar("ONBOOT") == 'no': continue
-
-        # don't bring up slave devices, the network scripts will
-        # handle those correctly
-        if getvar("SLAVE") == 'yes': continue
-
-        logger.verbose('net:InitInterfaces bringing up %s' % dev)
-        p = os.popen("/sbin/ifup %s" % dev)
-        # check for failure?
-        p.close()
+    pyplnet.InitInterfaces(logger, plc, data)
 
 def start(options, config):
     pass
index 17b02a3..d7e298b 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -11,9 +11,6 @@
 from distutils.core import setup, Extension
 
 setup(
-    ext_modules=[
-    Extension('sioc', ['sioc.c']),
-    ],
     py_modules=[
     'accounts',
     'api',
@@ -34,7 +31,6 @@ setup(
     'tools',
     'bwmon',
     'iptables',
-    'modprobe',
     ],
     scripts = [
     'forward_api_calls',
diff --git a/sioc.c b/sioc.c
deleted file mode 100644 (file)
index 0ddeb31..0000000
--- a/sioc.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Extension to gather information about network interfaces
- *
- * Mark Huang <mlhuang@cs.princeton.edu>
- * Copyright (C) 2006 The Trustees of Princeton University
- *
- * $Id$
- */
-
-#include <Python.h>
-
-/* struct ifreq */
-#include <net/if.h>
-
-/* socket() */
-#include <sys/types.h>
-#include <sys/socket.h>
-
-/* ioctl() */
-#include <sys/ioctl.h>
-
-/* inet_ntoa() */
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-/* ARPHRD_ETHER */
-#include <net/if_arp.h>
-
-/* ETH_ALEN */
-#include <net/ethernet.h>
-
-static PyObject *
-gifconf(PyObject *self, PyObject *args)
-{
-       struct ifconf ifc;
-       int len;
-       int s;
-       PyObject *addrs;
-       void *buf;
-       struct ifreq *ifr;
-       struct sockaddr_in *sin;
-
-       if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
-               return PyErr_SetFromErrno(PyExc_OSError);
-
-       len = sizeof(struct ifreq);
-       ifc.ifc_len = 0;
-       ifc.ifc_req = NULL;
-
-       do {
-               len *= 2;
-               buf = realloc(ifc.ifc_req, len);
-               if (!buf)
-                       break;
-               ifc.ifc_len = len;
-               ifc.ifc_req = buf;
-               if (ioctl(s, SIOCGIFCONF, &ifc) < 0)
-                       break;
-       } while (ifc.ifc_len >= len);
-
-       close(s);
-
-       addrs = Py_BuildValue("{}");
-
-       for (ifr = ifc.ifc_req, len = ifc.ifc_len; len > 0; ifr++, len -= sizeof(struct ifreq)) {
-               sin = (struct sockaddr_in *) &ifr->ifr_addr;
-               PyDict_SetItem(addrs,
-                              Py_BuildValue("s", ifr->ifr_name),
-                              Py_BuildValue("s", inet_ntoa(sin->sin_addr)));
-       }
-
-       if (ifc.ifc_req)
-               free(ifc.ifc_req);
-
-       return addrs;
-}
-
-static PyObject *
-gifaddr(PyObject *self, PyObject *args)
-{
-       const char *name;
-       struct ifreq ifr;
-       int s;
-       struct sockaddr_in *sin;
-
-       if (!PyArg_ParseTuple(args, "s", &name))
-               return NULL;
-
-       memset(&ifr, 0, sizeof(ifr));
-       strncpy(ifr.ifr_name, name, IFNAMSIZ);
-
-       if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
-               return PyErr_SetFromErrno(PyExc_OSError);
-
-       if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
-               close(s);
-               return PyErr_SetFromErrno(PyExc_OSError);
-       }
-
-       close(s);
-
-       sin = (struct sockaddr_in *) &ifr.ifr_addr;
-       return Py_BuildValue("s", inet_ntoa(sin->sin_addr));
-}
-
-static PyObject *
-gifhwaddr(PyObject *self, PyObject *args)
-{
-       const char *name;
-       struct ifreq ifr;
-       int s;
-       char mac[sizeof(ifr.ifr_hwaddr.sa_data) * 3], *c;
-       int len, i;
-
-       if (!PyArg_ParseTuple(args, "s", &name))
-               return NULL;
-
-       memset(&ifr, 0, sizeof(ifr));
-       strncpy(ifr.ifr_name, name, IFNAMSIZ);
-
-       if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
-               return PyErr_SetFromErrno(PyExc_OSError);
-
-       if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
-               close(s);
-               return PyErr_SetFromErrno(PyExc_OSError);
-       }
-
-       close(s);
-
-       switch (ifr.ifr_hwaddr.sa_family) {
-       case ARPHRD_ETHER:
-               len = ETH_ALEN;
-               break;
-       default:
-               len = sizeof(ifr.ifr_hwaddr.sa_data);
-               break;
-       }
-
-       for (i = 0, c = mac; i < len; i++) {
-               if (i)
-                       c += sprintf(c, ":");
-               c += sprintf(c, "%02X", (unsigned char)(ifr.ifr_hwaddr.sa_data[i] & 0xFF));
-       }
-
-       return Py_BuildValue("s", mac);
-}
-
-static PyMethodDef  methods[] = {
-       { "gifconf", gifconf, METH_VARARGS, "Get all interface addresses" },
-       { "gifaddr", gifaddr, METH_VARARGS, "Get interface address" },
-       { "gifhwaddr", gifhwaddr, METH_VARARGS, "Get interface hardware address" },
-       { NULL, NULL, 0, NULL }
-};
-
-PyMODINIT_FUNC
-initsioc(void)
-{
-       Py_InitModule("sioc", methods);
-}