use the FQDN for PLC_WWW_HOST rather than localhost to get cron.php
[myplc.git] / db-config
index 595975a..2c9f038 100755 (executable)
--- a/db-config
+++ b/db-config
@@ -7,11 +7,12 @@
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2006 The Trustees of Princeton University
 #
 # Mark Huang <mlhuang@cs.princeton.edu>
 # Copyright (C) 2006 The Trustees of Princeton University
 #
-# $Id: db-config 7454 2007-12-11 18:55:00Z faiyaza $
+# $Id$
 # $HeadURL$
 
 from plc_config import PLCConfiguration
 import sys
 # $HeadURL$
 
 from plc_config import PLCConfiguration
 import sys
+import resource
 
 def main():
     cfg = PLCConfiguration()
 
 def main():
     cfg = PLCConfiguration()
@@ -170,16 +171,34 @@ def main():
 
         # YUM configuration
         {'enabled': True,
 
         # YUM configuration
         {'enabled': True,
-         'source': 'PlanetLabConf/yum.conf.php?gpgcheck=1',
+         'source': 'PlanetLabConf/f8/yum.conf',
          'dest': '/etc/yum.conf',
          'dest': '/etc/yum.conf',
-         'file_permissions': '644',
-         'file_owner': 'root',
-         'file_group': 'root',
-         'preinstall_cmd': '',
-         'postinstall_cmd': '',
-         'error_cmd': '',
+         'file_permissions': '644', 'file_owner': 'root', 'file_group': 'root',
+         'preinstall_cmd': '', 'postinstall_cmd': '', 'error_cmd': '',
+         'ignore_cmd_errors': False,
+         'always_update': False},
+        {'enabled': True,
+         'source': 'PlanetLabConf/myplc.repo.php?gpgcheck=1',
+         'dest': '/etc/yum.myplc.d/myplc.repo',
+         'file_permissions': '644', 'file_owner': 'root', 'file_group': 'root',
+         'preinstall_cmd': '', 'postinstall_cmd': '', 'error_cmd': '',
+         'ignore_cmd_errors': False,
+         'always_update': False},
+        {'enabled': True,
+         'source': 'PlanetLabConf/f8/yum.myplc.d/fedora.repo',
+         'dest': '/etc/yum.myplc.d/fedora.repo',
+         'file_permissions': '644', 'file_owner': 'root', 'file_group': 'root',
+         'preinstall_cmd': '', 'postinstall_cmd': '', 'error_cmd': '',
          'ignore_cmd_errors': False,
          'always_update': False},
          'ignore_cmd_errors': False,
          'always_update': False},
+        {'enabled': True,
+         'source': 'PlanetLabConf/f8/yum.myplc.d/fedora-updates.repo',
+         'dest': '/etc/yum.myplc.d/fedora-updates.repo',
+         'file_permissions': '644', 'file_owner': 'root', 'file_group': 'root',
+         'preinstall_cmd': '', 'postinstall_cmd': '', 'error_cmd': '',
+         'ignore_cmd_errors': False,
+         'always_update': False},
+
         {'enabled': True,
          'source': 'PlanetLabConf/delete-rpm-list-production',
          'dest': '/etc/planetlab/delete-rpm-list',
         {'enabled': True,
          'source': 'PlanetLabConf/delete-rpm-list-production',
          'dest': '/etc/planetlab/delete-rpm-list',
@@ -238,34 +257,6 @@ def main():
          'ignore_cmd_errors': False,
          'always_update': False},
 
          'ignore_cmd_errors': False,
          'always_update': False},
 
-        # XXX Required for old Node Manager
-        # Proper configuration
-        {'enabled': True,
-         'source': 'PlanetLabConf/propd.conf',
-         'dest': '/etc/proper/propd.conf',
-         'file_permissions': '644',
-         'file_owner': 'root',
-         'file_group': 'root',
-         'preinstall_cmd': '',
-         'postinstall_cmd': '/etc/init.d/proper restart',
-         'error_cmd': '',
-         'ignore_cmd_errors': True,
-         'always_update': False},
-
-        # XXX Required for old Node Manager
-        # Bandwidth cap
-        {'enabled': True,
-         'source': 'PlanetLabConf/bwlimit.php',
-         'dest': '/etc/planetlab/bwcap',
-         'file_permissions': '644',
-         'file_owner': 'root',
-         'file_group': 'root',
-         'preinstall_cmd': '',
-         'postinstall_cmd': '',
-         'error_cmd': '',
-         'ignore_cmd_errors': True,
-         'always_update': False},
-
         # Proxy ARP setup
         {'enabled': True,
          'source': 'PlanetLabConf/proxies.php',
         # Proxy ARP setup
         {'enabled': True,
          'source': 'PlanetLabConf/proxies.php',
@@ -280,17 +271,6 @@ def main():
          'always_update': False},
 
         # Firewall configuration
          'always_update': False},
 
         # Firewall configuration
-        {'enabled': True,
-         'source': 'PlanetLabConf/iptables',
-         'dest': '/etc/sysconfig/iptables',
-         'file_permissions': '600',
-         'file_owner': 'root',
-         'file_group': 'root',
-         'preinstall_cmd': '',
-         'postinstall_cmd': '',
-         'error_cmd': '',
-         'ignore_cmd_errors': False,
-         'always_update': False},
         {'enabled': True,
          'source': 'PlanetLabConf/blacklist.php',
          'dest': '/etc/planetlab/blacklist',
         {'enabled': True,
          'source': 'PlanetLabConf/blacklist.php',
          'dest': '/etc/planetlab/blacklist',
@@ -393,7 +373,7 @@ def main():
 
         # sudo configuration
         {'enabled': True,
 
         # sudo configuration
         {'enabled': True,
-         'source': 'PlanetLabConf/sudoers',
+         'source': 'PlanetLabConf/sudoers.php',
          'dest': '/etc/sudoers',
          'file_permissions': '440',
          'file_owner': 'root',
          'dest': '/etc/sudoers',
          'file_permissions': '440',
          'file_owner': 'root',
@@ -497,9 +477,43 @@ def main():
         # Proper operations
         {'name': "proper_op",
          'description': "Proper operation (e.g. bind_socket)",
         # Proper operations
         {'name': "proper_op",
          'description': "Proper operation (e.g. bind_socket)",
-         'min_role_id': 10}
+         'min_role_id': 10},
+
+        # VServer capabilities 
+        {'name': "capabilities",
+         'description': "VServer bcapabilities (separate by commas)",
+         'min_role_id': 10},
+
+               # Vsys
+        {'name': "vsys",
+         'description': "Bind vsys script fd's to a slice's vsys directory.",
+         'min_role_id': 10},
+
+        # CoDemux
+        {'name': "codemux",
+         'description': "Demux HTTP between slices using localhost ports. Value in the form 'host, localhost port'.",
+         'min_role_id': 10},
+
+        # Delegation
+        {'name': "delegations",
+         'description': "Comma-seperated list of slices to give delegation authority to.",
+         'min_role_id': 10},
+
         ]
 
         ]
 
+    # add in the platform supported rlimits to the default_attribute_types
+    for entry in resource.__dict__.keys() + ["VLIMIT_OPENFD"]:
+        if entry.find("LIMIT_")==1:
+            rlim = entry[len("RLIMIT_"):]
+            rlim = rlim.lower()
+            for ty in ("min","soft","hard"):
+                attribute = {
+                    'name': "%s_%s"%(rlim,ty),
+                    'description': "Per sliver RLIMIT %s_%s."%(rlim,ty),
+                    'min_role_id': 10 #admin
+                    }
+                default_attribute_types.append(attribute)
+
     # Get list of existing attribute types
     attribute_types = GetSliceAttributeTypes()
     attribute_types = [attribute_type['name'] for attribute_type in attribute_types]
     # Get list of existing attribute types
     attribute_types = GetSliceAttributeTypes()
     attribute_types = [attribute_type['name'] for attribute_type in attribute_types]
@@ -512,18 +526,24 @@ def main():
             UpdateSliceAttributeType(default_attribute_type['name'], default_attribute_type)
 
     # Default Initscripts
             UpdateSliceAttributeType(default_attribute_type['name'], default_attribute_type)
 
     # Default Initscripts
-    default_initscripts = [
-        # Sirius 
-        {'enabled': True, 
-         'name': plc['slice_prefix'] + "_sirius", 
-         'script': '#!/usr/bin/python\n\n"""The Sirius Calendar Service.\n\nThis Python program runs on each node.  It periodically downloads the schedule file and uses NodeManager\'s XML-RPC interface to adjust the priority increase.\n\nAuthor: David Eisenstat (deisenst@cs.princeton.edu)\n\nOriginal Sirius implementation by David Lowenthal.\n"""\n\nimport fcntl\nimport os\nimport random\nimport signal\nimport socket\nimport sys\nimport threading\nimport time\nimport traceback\nimport urllib\nfrom xmlrpclib import ServerProxy\n\n\n# 0 means normal operation\n# 1 means turn on the short time scales and read the schedule from a file\n# 2 means additionally don\'t contact NodeManager\n\nDEBUGLEVEL = 0\n\n########################################\n\nif DEBUGLEVEL < 2:\n    LOGFILE = \'/var/log/sirius\'\nelse:\n    LOGFILE = \'log.txt\'\n\nloglock = threading.Lock()\n\n\ndef log(msg):\n    """Append <msg> and a timestamp to <LOGFILE>."""\n    try:\n        if not msg.endswith(\'\\n\'):\n            msg += \'\\n\'\n        loglock.acquire()\n        try:\n            logfile = open(LOGFILE, \'a\')\n            t = time.time()\n            print >>logfile, t\n            print >>logfile, time.asctime(time.gmtime(t))\n            print >>logfile, msg\n        finally:\n            loglock.release()\n    except:\n        if DEBUGLEVEL > 0:\n            traceback.print_exc()\n\n\ndef logexception():\n    """Log an exception."""\n    log(traceback.format_exc())\n\n########################################\n\nif DEBUGLEVEL > 0:\n    # smaller time units so we can test faster\n    ONEMINUTE = 1\n    ONEHOUR = 10 * ONEMINUTE\nelse:\n    ONEMINUTE = 60\n    ONEHOUR = 60 * ONEMINUTE\n\n\nclass Periodic:\n    """Periodically make a function call."""\n\n    def __init__(self, target, interval, mindelta, maxdelta):\n        self._target = target\n        self._interval = interval\n        self._deltarange = mindelta, maxdelta+1\n        thr = threading.Thread(target=self.run, args=[target])\n        thr.setDaemon(True)\n        thr.start()\n\n    def run(self, target):\n        nextintervalstart = int(time.time() / self._interval) * self._interval\n        while True:\n            try:\n                self._target()\n            except:\n                logexception()\n            nextintervalstart += self._interval\n            nextfiring = nextintervalstart + random.randrange(*self._deltarange)\n            while True:\n                t = time.time()\n                if t < nextfiring:\n                    try:\n                        time.sleep(nextfiring - t)\n                    except:\n                        logexception()\n                else:\n                    break\n\n########################################\n\nSLOTDURATION = ONEHOUR\n\nSCHEDULEURL = \'' + site['url'] + '/planetlab/sirius/schedule.txt\'\n\nschedulelock = threading.Lock()\n\nschedule = {}\n\n\ndef currentslot():\n    return int(time.time() / SLOTDURATION) * SLOTDURATION\n\n\ndef updateschedule():\n    """Make one attempt at downloading and updating the schedule."""\n    log(\'Contacting PLC...\')\n    newschedule = {}\n    # Format is:\n    # timestamp\n    # slicename - starttime - -\n    # ...\n    if DEBUGLEVEL > 0:\n        f = open(\'/tmp/schedule.txt\')\n    else:\n        f = urllib.urlopen(SCHEDULEURL)\n    for line in f:\n        fields = line.split()\n        if len(fields) >= 3:\n            newschedule[fields[2]] = fields[0]\n    log(\'Current schedule is %s\' % newschedule)\n\n    schedulelock.acquire()\n    try:\n        schedule.clear()\n        schedule.update(newschedule)\n    finally:\n        schedulelock.release()\n    log(\'Updated schedule successfully\')\n\n########################################\n\nnodemanager = ServerProxy(\'http://127.0.0.1:812/\')\n\nrecipientcond = threading.Condition()\n\nrecipient = \'\'\nversionnumber = 0\n\ndef updateloans():\n    log(\'Contacting NodeManager...\')\n    schedulelock.acquire()\n    try:\n        newrecipient = schedule.get(str(currentslot()), \'\')\n    finally:\n        schedulelock.release()\n    if newrecipient:\n        loans = [(newrecipient, \'cpu_pct\', 25), (newrecipient, \'net_min_rate\', 2000)]\n    else:\n        loans = []\n    log(\'Current loans are %s\' % loans)\n\n    if DEBUGLEVEL < 2:\n        nodemanager.SetLoans(\'princeton_sirius\', loans)\n    log(\'Updated loans successfully\')\n\n    recipientcond.acquire()\n    try:\n        global recipient, versionnumber\n        if recipient != newrecipient:\n            recipient = newrecipient\n            versionnumber += 1\n            recipientcond.notifyAll()\n    finally:\n        recipientcond.release()\n\n########################################\n\nbackoff = 1\n\ndef success():\n    global backoff\n    backoff = 1\n\ndef failure():\n    global backoff\n    try:\n        time.sleep(backoff)\n    except:\n        logexception()\n    backoff = min(backoff*2, 5*ONEMINUTE)\n\n\ndef handleclient(clientsock, clientaddress):\n    try:\n        log(\'Connection from %s:%d\' % clientaddress)\n        clientsock.shutdown(socket.SHUT_RD)\n        recipientcond.acquire()\n        while True:\n            recip, vn = recipient, versionnumber\n            recipientcond.release()\n            clientsock.send(recip + \'\\n\')\n\n            recipientcond.acquire()\n            while versionnumber == vn:\n                recipientcond.wait()\n    except:\n        logexception()\n\n\ndef server():\n    while True:\n        try:\n            sock = socket.socket()\n            sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n            sock.bind((\'\', 8124))\n            sock.listen(5)\n            success()\n            break\n        except:\n            logexception()\n            failure()\n    log(\'Bound server socket\')\n\n    while True:\n        try:\n            client = sock.accept()\n            threading.Thread(target=handleclient, args=client).start()\n            success()\n        except:\n            logexception()\n            failure()\n\n########################################\n\nif DEBUGLEVEL < 2:\n    PIDFILE = \'/tmp/sirius.pid\'\nelse:\n    PIDFILE = \'sirius.pid\'\n\ntry:\n    if os.fork():\n        sys.exit(0)\n    f = open(PIDFILE, \'w\')\n    fcntl.flock(f.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)\nexcept:\n    logexception()\n    sys.exit(1)\n\nPeriodic(updateschedule, SLOTDURATION, -5*ONEMINUTE, -1*ONEMINUTE)\nPeriodic(updateloans, 5*ONEMINUTE, 0, 0)\nserver()\n'}]
-    
+    default_initscripts = []
+
+    # Find initscripts and add them to the db
+    for (root, dirs, files) in os.walk("/etc/plc_sliceinitscripts"):
+        for f in files:
+            # Read the file
+            file = open(root + "/" + f, "ro")
+            default_initscripts.append({"name": plc['slice_prefix'] + "_" + f,
+                                        "enabled": True,
+                                        "script": file.read().replace("@SITE@", url).replace("@PREFIX@", plc['slice_prefix'])})
+            file.close()
+
     # Get list of existing initscripts
     oldinitscripts = GetInitScripts()
     oldinitscripts = [script['name'] for script in oldinitscripts]
 
     for initscript in default_initscripts:
     # Get list of existing initscripts
     oldinitscripts = GetInitScripts()
     oldinitscripts = [script['name'] for script in oldinitscripts]
 
     for initscript in default_initscripts:
-        if initscript not in oldinitscripts:  AddInitScript(initscript)
+        if initscript['name'] not in oldinitscripts:  AddInitScript(initscript)
 
     # Setup default slice attribute types
     default_setting_types = [
 
     # Setup default slice attribute types
     default_setting_types = [
@@ -532,13 +552,9 @@ def main():
          'name' : "ifname",
          'description': "Set interface name, instead of eth0 or the like",
          'min_role_id' : 40},
          'name' : "ifname",
          'description': "Set interface name, instead of eth0 or the like",
          'min_role_id' : 40},
-        {'category' : "general",
-         'name' : "driver",
-         'description': "Use this to specify an alternate driver",
-         'min_role_id' : 40 },
-        {'category' : "general",
+        {'category' : "Multihome",
          'name' : "alias",
          'name' : "alias",
-         'description': "Allows to reuse an interface as eth0:alias",
+         'description': "Specifies that the network is used for multihoming",
          'min_role_id' : 40},
 
         {'category' : "hidden",
          'min_role_id' : 40},
 
         {'category' : "hidden",
@@ -584,23 +600,21 @@ def main():
     default_slices = [
          # PlanetFlow
         {'name': plc['slice_prefix'] + "_netflow",
     default_slices = [
          # PlanetFlow
         {'name': plc['slice_prefix'] + "_netflow",
-         'description': "PlanetFlow Traffic Auditing Service",
+         'description': "PlanetFlow Traffic Auditing Service.  Logs, captured in the root context using fprobe-ulogd, are stored in a directory in the root context which is bind mounted to the planetflow slice.  The Planetflow Central service then periodically rsyncs these logs from the planetflow slice for aggregation.",
          'url': url,
          'instantiation': "plc-instantiated",
          'url': url,
          'instantiation': "plc-instantiated",
-         # Renew forever
-         'expires': sys.maxint,
+         # Renew forever (minus one day, work around date conversion weirdness)
+         'expires': 0x7fffffff - (60 * 60 * 24),
          'attributes': [('system', "1"),
                         ('vref', "planetflow"),
          'attributes': [('system', "1"),
                         ('vref', "planetflow"),
-                        ('proper_op', "open file=/etc/passwd, flags=r"),
-                        ('proper_op', "create_socket"),
-                        ('proper_op', "bind_socket")]},
+                                               ('vsys', "pfmount")]},
           # Sirius
         {'name': plc['slice_prefix'] + "_sirius",
          'description': 'The Sirius Calendar Service.\n\nSirius provides system-wide reservations of 25% CPU and 2Mb/s outgoing\nbandwidth.  Sign up for hour-long slots using the Web GUI at the\nPlanetLab website.\n\nThis slice should not generate traffic external to PlanetLab.\n',
           # Sirius
         {'name': plc['slice_prefix'] + "_sirius",
          'description': 'The Sirius Calendar Service.\n\nSirius provides system-wide reservations of 25% CPU and 2Mb/s outgoing\nbandwidth.  Sign up for hour-long slots using the Web GUI at the\nPlanetLab website.\n\nThis slice should not generate traffic external to PlanetLab.\n',
-         'url': url,
+         'url': url + "db/sirius/index.php",
          'instantiation': "plc-instantiated",
          'instantiation': "plc-instantiated",
-         # Renew forever
-         'expires': sys.maxint,
+         # Renew forever (minus one day, work around date conversion weirdness)
+         'expires': 0x7fffffff - (60 * 60 * 24),
          'attributes': [('system', "1"),
                         ('net_min_rate', "2000"),
                         ('cpu_pct', "25"),
          'attributes': [('system', "1"),
                         ('net_min_rate', "2000"),
                         ('cpu_pct', "25"),
@@ -766,24 +780,18 @@ requirements.
 
 The most common reason for authentication failure is that the
 authentication key stored in the node configuration file, does not
 
 The most common reason for authentication failure is that the
 authentication key stored in the node configuration file, does not
-match the key on record. 
+match the key stored in our database.  These keys must match in order to
+authenticate the node successfully.
 
 
-There are two possible steps to resolve the problem.
+Each time the configuration file is downloaded, either as part of an All-in-One
+BootImage or by downloading the plnode.txt file, the authentication key is
+RECREATED.  So, which ever file was downloaded most recently is the one we
+have in our database.  Often, users will download both the All-in-One image as
+well as the plnode.txt file, and inadvertently break the boot image.
 
 
-1. If you have used an All-in-one BootCD that includes the plnode.txt file,
-    then please check your machine for any old boot media, either in the
-    floppy drive, or on a USB stick.  It is likely that an old configuration
-    is being used instead of the new configuration stored on the BootCD.
-Or, 
-2. If you are using Generic BootCD image, then regenerate the node 
-    configuration file by visiting:
-
-    https://%(PLC_WWW_HOST)s:%(PLC_WWW_SSL_PORT)d/db/nodes/?id=%(node_id)d
-
-    Under 'Download', follow the 'Download plnode.txt file for %(hostname)s'
-    option, and save the downloaded file as plnode.txt on either a floppy 
-    disk or a USB flash drive.  Be sure the 'Boot State' is set to 'Boot', 
-    and, then reboot the node.
+To repair this problem, simply download your All-in-One BootImage again, and
+copy it to the appropriate read-only boot media (write-protected USB or
+CD-ROM).  
 
 If you have already performed this step and are still receiving this
 message, please reply so that we can help investigate the problem.
 
 If you have already performed this step and are still receiving this
 message, please reply so that we can help investigate the problem.
@@ -1001,6 +1009,21 @@ message, please reply so that we may investigate the problem.
             for ptype in protocol_types:
                 AddPCUProtocolType(id, ptype)
 
             for ptype in protocol_types:
                 AddPCUProtocolType(id, ptype)
 
+    # Run local db-config snippets
+    files = []
+    dir = "/etc/planetlab/db-config.d"
+    try:
+        files = os.listdir(dir)
+    except:
+        pass
+
+    for file in files:
+        if (file.endswith(".bak") or file.endswith("~") or
+            file.endswith(".rpmsave") or file.endswith(".rpmnew") or
+            file.endswith(".orig")):
+            continue
+        execfile(os.path.join(dir, file))
+
 
 if __name__ == '__main__':
     main()
 
 if __name__ == '__main__':
     main()