add steps to build and install Monitor docs into plc
[myplc.git] / db-config
index a773320..4a1a22d 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
 #
-# $Id: db-config,v 1.22 2007/02/02 23:40:22 mlhuang Exp $
-#
+# $Id$
+# $HeadURL$
 
 from plc_config import PLCConfiguration
 import sys
+import resource
 
 def main():
     cfg = PLCConfiguration()
@@ -54,7 +55,7 @@ def main():
              'name': plc['name'] + " Central",
              'abbreviated_name': plc['name'],
              'login_base': plc['slice_prefix'],
-             'is_public': True,
+             'is_public': False,
              'url': url,
              'max_slices': 100 }
 
@@ -80,6 +81,215 @@ def main():
     AddRoleToPerson(10, admin['person_id'])
     AddRoleToPerson(20, admin['person_id'])
 
+    #################### node tags
+    default_node_types = [
+        { 'tagname' : 'arch',
+          'description' : 'architecture name',
+          'category' : 'node/config', 
+          'min_role_id' : 40} ,
+        { 'tagname' : 'pldistro',
+          'description' : 'PlanetLab distribution',
+          'category' : 'node/config', 
+          'min_role_id' : 10} ,
+        { 'tagname' : 'deployment',
+          'description' : 'typically "alpha", "beta", or "production"',
+          'category' : 'node/operation', 
+          'min_role_id' : 10} ,
+        ]
+
+    #################### interface settings
+    # xxx this should move to PLC/Accessors
+
+    # Setup default slice attribute types
+    default_setting_types = [
+        {'category' : "interface/general",
+         'tagname' : "ifname",
+         'description': "Set interface name, instead of eth0 or the like",
+         'min_role_id' : 40},
+        {'category' : "interface/multihome",
+         'tagname' : "alias",
+         'description': "Specifies that the network is used for multihoming",
+         'min_role_id' : 40},
+
+        {'category' : "interface/hidden",
+         'tagname' : "backdoor",
+         'description': "For testing new settings",
+         'min_role_id' : 10},
+        ] + [
+        { 'category' : "interface/wifi",
+          'tagname' : x,
+          'description' : "802.11 %s -- see %s"%(y,z),
+          'min_role_id' : 40 } for (x,y,z) in [
+            ("mode","Mode","iwconfig"),
+            ("essid","ESSID","iwconfig"),
+            ("nw","Network Id","iwconfig"),
+            ("freq","Frequency","iwconfig"),
+            ("channel","Channel","iwconfig"),
+            ("sens","sensitivity threshold","iwconfig"),
+            ("rate","Rate","iwconfig"),
+            ("key","key","iwconfig key"),
+            ("key1","key1","iwconfig key [1]"),
+            ("key2","key2","iwconfig key [2]"),
+            ("key3","key3","iwconfig key [3]"),
+            ("key4","key4","iwconfig key [4]"),
+            ("securitymode","Security mode","iwconfig enc"),
+            ("iwconfig","Additional parameters to iwconfig","ifup-wireless"),
+            ("iwpriv","Additional parameters to iwpriv","ifup-wireless"),
+            ]
+        ]
+
+    #################### slice attributes
+    # xxx this should move to PLC/Accessors
+
+    # Setup default slice attribute types
+    default_attribute_types = [
+        # Slice type (only vserver is supported)
+        {'tagname': "type",
+         'description': "Type of slice (e.g. vserver)",
+         'category' : 'slice/general',
+         'min_role_id': 20},
+
+        # System slice
+        {'tagname': "system",
+         'description': "Is a default system slice (1) or not (0 or unset)",
+         'category' : 'slice/general',
+         'min_role_id': 10},
+
+        # Slice enabled (1) or suspended (0)
+        {'tagname': "enabled",
+         'description': "Slice enabled (1 or unset) or suspended (0)",
+         'category' : 'slice/general',
+         'min_role_id': 10},
+
+        # Slice reference image
+        {'tagname': "vref",
+         'description': "Reference image",
+         'category' : 'slice/config',
+         'min_role_id': 30},
+
+        # Slice initialization script
+        {'tagname': "initscript",
+         'description': "Slice initialization script",
+         'category' : 'slice/config',
+         'min_role_id': 10},
+
+        # CPU share
+        {'tagname': "cpu_pct",
+         'description': "Reserved CPU percent",
+         'category' : 'slice/rspec',
+         'min_role_id': 10},
+        {'tagname': "cpu_share",
+         'description': "Number of CPU shares",
+         'category' : 'slice/rspec',
+         'min_role_id': 10},
+
+        # Bandwidth limits
+        {'tagname': "net_min_rate",
+         'description': "Minimum bandwidth (kbps)",
+         'category' : 'slice/rspec',
+         'min_role_id': 10},
+        {'tagname': "net_max_rate",
+         'description': "Maximum bandwidth (kbps)",
+         'category' : 'slice/rspec',
+         'min_role_id': 10},
+        {'tagname': "net_i2_min_rate",
+         'description': "Minimum bandwidth over I2 routes (kbps)",
+         'category' : 'slice/rspec',
+         'min_role_id': 10},
+        {'tagname': "net_i2_max_rate",
+         'description': "Maximum bandwidth over I2 routes (kbps)",
+         'category' : 'slice/rspec',
+         'min_role_id': 10},
+        {'tagname': "net_max_kbyte",
+         'description': "Maximum daily network Tx KByte limit.",
+         'category' : 'slice/rspec',
+         'min_role_id': 10},
+        {'tagname': "net_thresh_kbyte",
+         'description': "KByte limit before warning and throttling.",
+         'category' : 'slice/rspec',
+         'min_role_id': 10},
+        {'tagname': "net_i2_max_kbyte",
+         'description': "Maximum daily network Tx KByte limit to I2 hosts.",
+         'category' : 'slice/rspec',
+         'min_role_id': 10},
+        {'tagname': "net_i2_thresh_kbyte",
+         'description': "KByte limit to I2 hosts before warning and throttling.",
+         'category' : 'slice/rspec',
+         'min_role_id': 10},
+        {'tagname': "net_share",
+         'description': "Number of bandwidth shares",
+         'category' : 'slice/rspec',
+         'min_role_id': 10},
+        {'tagname': "net_i2_share",
+         'description': "Number of bandwidth shares over I2 routes",
+         'category' : 'slice/rspec',
+         'min_role_id': 10},
+        # Disk quota
+        {'tagname': "disk_max",
+         'description': "Disk quota (1k disk blocks)",
+         'category' : 'slice/rspec',
+         'min_role_id': 10},
+
+        # Proper operations
+        {'tagname': "proper_op",
+         'description': "Proper operation (e.g. bind_socket)",
+         'category' : 'slice/rspec',
+         'min_role_id': 10},
+
+        # VServer capabilities 
+        {'tagname': "capabilities",
+         'description': "VServer bcapabilities (separate by commas)",
+         'category' : 'slice/rspec',
+         'min_role_id': 10},
+
+        # Vsys
+        {'tagname': "vsys",
+         'description': "Bind vsys script fd's to a slice's vsys directory.",
+         'category' : 'slice/rspec',
+         'min_role_id': 10},
+
+        # CoDemux
+        {'tagname': "codemux",
+         'description': "Demux HTTP between slices using localhost ports. Value in the form 'host, localhost port'.",
+         'category' : 'slice/rspec',
+         'min_role_id': 10},
+
+        # Delegation
+        {'tagname': "delegations",
+         'description': "Coma seperated list of slices to give delegation authority to.",
+         'category' : 'slice/rspec',
+         '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 = {
+                    'tagname': "%s_%s"%(rlim,ty),
+                    'description': "Per sliver RLIMIT %s_%s."%(rlim,ty),
+                    'category': 'slice/limit',
+                    'min_role_id': 10 #admin
+                    }
+                default_attribute_types.append(attribute)
+
+    # Get list of existing tag types
+    known_tag_types = [tag_type['tagname'] for tag_type in GetTagTypes()]
+
+    all_default_types = default_node_types + default_setting_types + default_attribute_types
+    # Create/update default slice tag types
+    for default_tag_type in all_default_types:
+        if default_tag_type['tagname'] not in known_tag_types:
+            AddTagType(default_tag_type)
+        else:
+            UpdateTagType(default_tag_type['tagname'], default_tag_type)
+
+    #################### conf files
+
     # Setup default PlanetLabConf entries
     default_conf_files = [
         # NTP configuration
@@ -142,18 +352,6 @@ def main():
          'error_cmd': '',
          'ignore_cmd_errors': False,
          'always_update': False},
-        {'enabled': True,
-         'source': 'PlanetLabConf/keys.php?role=admin',
-         'dest': '/home/pl_admin/.ssh/authorized_keys',
-         'file_permissions': '644',
-         'file_owner': 'pl_admin',
-         'file_group': 'pl_admin',
-         'preinstall_cmd': 'grep -q pl_admin /etc/passwd',
-         'postinstall_cmd': '/bin/chmod 700 /home/pl_admin/.ssh',
-         'error_cmd': '',
-         'ignore_cmd_errors': False,
-         'always_update': False},
-
         # Log rotation configuration
         {'enabled': True,
          'source': 'PlanetLabConf/logrotate.conf',
@@ -182,16 +380,27 @@ def main():
 
         # YUM configuration
         {'enabled': True,
-         'source': 'PlanetLabConf/yum.conf.php?gpgcheck=1',
+         'source': 'yum/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': 'yum/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': 'yum/stock.repo',
+         'dest': '/etc/yum.myplc.d/stock.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',
@@ -250,81 +459,6 @@ def main():
          'ignore_cmd_errors': False,
          'always_update': False},
 
-        # XXX Required for old Node Manager
-        # Node Manager configuration
-        {'enabled': True,
-         'source': 'PlanetLabConf/pl_nm.conf',
-         'dest': '/etc/planetlab/pl_nm.conf',
-         'file_permissions': '644',
-         'file_owner': 'root',
-         'file_group': 'root',
-         'preinstall_cmd': '',
-         'postinstall_cmd': '/etc/init.d/pl_nm restart',
-         'error_cmd': '',
-         'ignore_cmd_errors': False,
-         'always_update': False},
-        {'enabled': True,
-         'source': 'PlanetLabConf/RootResources/plc_slice_pool.php',
-         'dest': '/home/pl_nm/RootResources/plc_slice_pool',
-         'file_permissions': '644',
-         'file_owner': 'pl_nm',
-         'file_group': 'pl_nm',
-         'preinstall_cmd': '',
-         'postinstall_cmd': '',
-         'error_cmd': '',
-         'ignore_cmd_errors': False,
-         'always_update': False},
-        {'enabled': True,
-         'source': 'PlanetLabConf/RootResources/pl_conf.py',
-         'dest': '/home/pl_nm/RootResources/pl_conf',
-         'file_permissions': '644',
-         'file_owner': 'pl_nm',
-         'file_group': 'pl_nm',
-         'preinstall_cmd': '',
-         'postinstall_cmd': '/etc/init.d/pl_nm restart',
-         'error_cmd': '',
-         'ignore_cmd_errors': False,
-         'always_update': False},
-        {'enabled': True,
-         'source': 'PlanetLabConf/RootResources/pl_netflow.py',
-         'dest': '/home/pl_nm/RootResources/pl_netflow',
-         'file_permissions': '644',
-         'file_owner': 'pl_nm',
-         'file_group': 'pl_nm',
-         'preinstall_cmd': '',
-         'postinstall_cmd': '',
-         'error_cmd': '',
-         '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': '/etc/init.d/pl_nm restart',
-         'error_cmd': '',
-         'ignore_cmd_errors': True,
-         'always_update': False},
-
         # Proxy ARP setup
         {'enabled': True,
          'source': 'PlanetLabConf/proxies.php',
@@ -339,17 +473,6 @@ def main():
          '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',
@@ -437,6 +560,7 @@ def main():
          'always_update': False},
 
         # Ping of death configuration
+        # the 'restart' postcommand doesn't work, b/c the pod script doesn't support it.
         {'enabled': True,
          'source': 'PlanetLabConf/ipod.conf.php',
          'dest': '/etc/ipod.conf',
@@ -444,14 +568,14 @@ def main():
          'file_owner': 'root',
          'file_group': 'root',
          'preinstall_cmd': '',
-         'postinstall_cmd': '',
+         'postinstall_cmd': '/etc/init.d/pod start',
          'error_cmd': '',
          'ignore_cmd_errors': False,
          'always_update': False},
 
         # sudo configuration
         {'enabled': True,
-         'source': 'PlanetLabConf/sudoers',
+         'source': 'PlanetLabConf/sudoers.php',
          'dest': '/etc/sudoers',
          'file_permissions': '440',
          'file_owner': 'root',
@@ -480,160 +604,56 @@ def main():
             conf_file = conf_files[default_conf_file['dest']]
             UpdateConfFile(conf_file['conf_file_id'], default_conf_file)
 
-    # Setup default slice attribute types
-    default_attribute_types = [
-        # Slice type (only vserver is supported)
-        {'name': "type",
-         'description': "Type of slice (e.g. vserver)",
-         'min_role_id': 20},
-
-        # System slice
-        {'name': "system",
-         'description': "Is a default system slice (1) or not (0 or unset)",
-         'min_role_id': 10},
-
-        # Slice enabled (1) or suspended (0)
-        {'name': "enabled",
-         'description': "Slice enabled (1 or unset) or suspended (0)",
-         'min_role_id': 10},
-
-        # Slice reference image
-        {'name': "vref",
-         'description': "Reference image",
-         'min_role_id': 30},
-
-        # Slice initialization script
-        {'name': "initscript",
-         'description': "Slice initialization script",
-         'min_role_id': 10},
-
-        # CPU share
-        {'name': "cpu_min",
-         'description': "Minimum CPU share (ms/s)",
-         'min_role_id': 10},
-        {'name': "cpu_share",
-         'description': "Number of CPU shares",
-         'min_role_id': 10},
 
-        # Bandwidth limits
-        {'name': "net_min_rate",
-         'description': "Minimum bandwidth (kbps)",
-         'min_role_id': 10},
-        {'name': "net_max_rate",
-         'description': "Maximum bandwidth (kbps)",
-         'min_role_id': 10},
-        {'name': "net_i2_min_rate",
-         'description': "Minimum bandwidth over I2 routes (kbps)",
-         'min_role_id': 10},
-        {'name': "net_i2_max_rate",
-         'description': "Maximum bandwidth over I2 routes (kbps)",
-         'min_role_id': 10},
-        {'name': "net_max_kbyte",
-         'description': "Maximum daily network Tx KByte limit.",
-         'min_role_id': 10},
-        {'name': "net_thresh_kbyte",
-         'description': "KByte limit before warning and throttling.",
-         'min_role_id': 10},
-        {'name': "net_i2_max_kbyte",
-         'description': "Maximum daily network Tx KByte limit to I2 hosts.",
-         'min_role_id': 10},
-        {'name': "net_i2_thresh_kbyte",
-         'description': "KByte limit to I2 hosts before warning and throttling.",
-         'min_role_id': 10},
-        {'name': "net_share",
-         'description': "Number of bandwidth shares",
-         'min_role_id': 10},
-        {'name': "net_i2_share",
-         'description': "Number of bandwidth shares over I2 routes",
-         'min_role_id': 10},
-        # Disk quota
-        {'name': "disk_max",
-         'description': "Disk quota (1k disk blocks)",
-         'min_role_id': 10},
+    #################### initscripts
 
-        # Proper operations
-        {'name': "proper_op",
-         'description': "Proper operation (e.g. bind_socket)",
-         'min_role_id': 10},
+    # Default Initscripts
+    default_initscripts = []
 
-        # XXX Required for old Node Manager
-        # Special attributes applicable to Slice Creation Service (pl_conf) slice
-        {'name': "plc_slice_type",
-         'description': "Type of slice rspec to be created",
-         'min_role_id': 20},
-        {'name': "plc_agent_version",
-         'description': "Version of PLC agent (slice creation service) software to be deployed",
-         'min_role_id': 10},
-        {'name': "plc_ticket_pubkey",
-         'description': "Public key used to verify PLC-signed tickets",
-         'min_role_id': 10}
-        ]
+    # 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 attribute types
-    attribute_types = GetSliceAttributeTypes()
-    attribute_types = [attribute_type['name'] for attribute_type in attribute_types]
+    # Get list of existing initscripts
+    oldinitscripts = GetInitScripts()
+    oldinitscripts = [script['name'] for script in oldinitscripts]
 
-    # Create/update default slice attribute types
-    for default_attribute_type in default_attribute_types:
-        if default_attribute_type['name'] not in attribute_types:
-            AddSliceAttributeType(default_attribute_type)
-        else:
-            UpdateSliceAttributeType(default_attribute_type['name'], default_attribute_type)
+    for initscript in default_initscripts:
+        if initscript['name'] not in oldinitscripts:  AddInitScript(initscript)
 
     # Create/update system slices
-    legacy_slices = [
-        # XXX Required for old Node Manager
-        {'name': "pl_conf",
-         'description': "PlanetLab Slice Creation Service (SCS)",
-         'url': url,
-         'instantiation': "plc-instantiated",
-         # Renew forever
-         'expires': sys.maxint,
-         'attributes': [('plc_slice_type', "VServerSlice"),
-                        ('plc_agent_version', "1.0"),
-                        ('plc_ticket_pubkey', "")]},
-
-        # XXX Required for old Node Manager
-        {'name': "pl_conf_vserverslice",
-         'description': "Default attributes for vserver slices",
-         'url': url,
-         'instantiation': "plc-instantiated",
-         # Renew forever
-         'expires': sys.maxint,
-         'attributes': [('cpu_share', "32"),
-                        ('plc_slice_type', "VServerSlice"),
-                        ('disk_max', "5000000")]},
-        ]
     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",
-         # 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"),
-                        ('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',
+         'url': url + "db/sirius/index.php",
+         'instantiation': "plc-instantiated",
+         # 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"),
+                        ('initscript', plc['slice_prefix'] + "_sirius")]}
         ]
-         
-    ### xxx - to review once new node manager rolls out
-    # if PLC_SLICE_PREFIX is left to default - this is meant for the public PL only
-    if plc['slice_prefix'] == 'pl':
-        # create both legacy slices together with netflow through default_slices
-        default_slices += legacy_slices
-    else:
-        # we use another slice prefix : disable legacy slices if already created
-        for legacy_slice in legacy_slices:
-            try:
-                DeleteSlice(legacy_slice['name'])
-            except:
-                pass
     
     for default_slice in default_slices:
+        attributes=default_slice.pop('attributes')
         slices = GetSlices([default_slice['name']])
         if slices:
             slice = slices[0]
@@ -643,19 +663,22 @@ def main():
             slice = GetSlices([default_slice['name']])[0]
 
         # Create/update all attributes
-        slice_attributes = []
-        if slice['slice_attribute_ids']:
+        slice_tags = []
+        if slice['slice_tag_ids']:
             # Delete unknown attributes
-            for slice_attribute in GetSliceAttributes(slice['slice_attribute_ids']):
-                if (slice_attribute['name'], slice_attribute['value']) \
-                   not in default_slice['attributes']:
-                    DeleteSliceAttribute(slice_attribute['slice_attribute_id'])
+            for slice_tag in GetSliceTags(slice['slice_tag_ids']):
+                if (slice_tag['tagname'], slice_tag['value']) \
+                   not in attributes:
+                    DeleteSliceTag(slice_tag['slice_tag_id'])
                 else:
-                    slice_attributes.append((slice_attribute['name'], slice_attribute['value']))
+                    slice_tags.append((slice_tag['tagname'], slice_tag['value']))
 
-        for (name, value) in default_slice['attributes']:
-            if (name, value) not in slice_attributes:
-                AddSliceAttribute(slice['name'], name, value)
+        for (name, value) in attributes:
+            if (name, value) not in slice_tags:
+                AddSliceTag(slice['name'], name, value)
+
+    
+    #################### body for messages
 
     installfailed = """
 Once the node meets these requirements, please reinitiate the install
@@ -663,7 +686,7 @@ by visiting:
 
 https://%(PLC_WWW_HOST)s:%(PLC_WWW_SSL_PORT)d/db/nodes/?id=%(node_id)d
 
-Click the Reinstall link, then reboot the node.
+Update the BootState to 'Reinstall', then reboot the node.
 
 If you have already performed this step and are still receiving this
 message, please reply so that we may investigate the problem.
@@ -679,6 +702,8 @@ username %(email)s by visiting:
 
 https://%(PLC_WWW_HOST)s:%(PLC_WWW_SSL_PORT)d/db/persons/register.php?id=%(person_id)d&key=%(verification_key)s
 
+You must wait for this account to be approved before you can begin using it, please be patient.
+
 If you did not register for a %(PLC_NAME)s account, please ignore this
 message, or contact %(PLC_NAME)s Support <%(PLC_MAIL_SUPPORT_ADDRESS)s>.
 """
@@ -792,17 +817,27 @@ requirements.
 
 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. Regenerate the node configuration file by
-visiting:
+match the key on record. 
 
-https://%(PLC_WWW_HOST)s:%(PLC_WWW_SSL_PORT)d/db/nodes/?id=%(node_id)d
+There are two possible steps to resolve the problem.
 
-Click the Configuration File link, and save the downloaded file as
-plnode.txt on either a floppy disk or a USB flash drive. Click the
-Boot link, then reboot the node.
+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.
 
 If you have already performed this step and are still receiving this
-message, please reply so that we may investigate the problem.
+message, please reply so that we can help investigate the problem.
 """
          },
 
@@ -818,7 +853,7 @@ doing so, visit:
 
 https://%(PLC_WWW_HOST)s:%(PLC_WWW_SSL_PORT)d/db/nodes/?id=%(node_id)d
 
-Click the Reinstall link, then reboot the node.
+Change the 'Boot State' to 'Reinstall', and then reboot the node.
 
 If you have already performed this step and are still receiving this
 message, please reply so that we may investigate the problem.
@@ -837,7 +872,8 @@ hostname, IP address, and DNS servers, by visiting:
 
 https://%(PLC_WWW_HOST)s:%(PLC_WWW_SSL_PORT)d/db/nodes/?id=%(node_id)d
 
-Correct any errors, click the Reinstall link, then reboot the node.
+Correct any errors, and change the 'Boot State' to 'Reinstall', and then
+reboot the node.
 
 If you have already performed this step and are still receiving this
 message, please reply so that we may investigate the problem.
@@ -857,8 +893,8 @@ configuration file. To create this file, visit:
 https://%(PLC_WWW_HOST)s:%(PLC_WWW_SSL_PORT)d/db/nodes/?id=%(node_id)d
 
 Click the Configuration File link, and save the downloaded file as
-plnode.txt on either a floppy disk or a USB flash drive. Click the
-Reinstall link, then reboot the node.
+plnode.txt on either a floppy disk or a USB flash drive.  Change the 
+'Boot State' to 'Reinstall', and then reboot the node.
 
 If you have already performed this step and are still receiving this
 message, please reply so that we may investigate the problem.
@@ -876,7 +912,7 @@ successfully in the past, please try re-installing it by visiting:
 
 https://%(PLC_WWW_HOST)s:%(PLC_WWW_SSL_PORT)d/db/nodes/?id=%(node_id)d
 
-Click the Reinstall link, then reboot the node.
+Change the 'Boot State' to 'Reinstall', and then reboot the node.
 
 If you have already performed this step and are still receiving this
 message, please reply so that we may investigate the problem.
@@ -885,9 +921,117 @@ message, please reply so that we may investigate the problem.
         ]
 
     for template in message_templates:
-       messages = GetMessages([template['message_id']])
-       if not messages:
-            AddMessage(template)       
+        messages = GetMessages([template['message_id']])
+        if not messages:
+            AddMessage(template)
+
+    #################### PCUs
+    
+    ### Setup Initial PCU information
+       pcu_types = [
+                        {'model': 'APCControl12p3',
+                         'name': 'APC AP79xx or Masterswitch (sequence 1-2-port-3)', },
+                        {'model': 'APCControl1p4',
+                         'name': 'APC AP79xx or Masterswitch (sequence 1-port-4)', },
+                        {'model': 'APCControl121p3',
+                         'name': 'APC AP79xx or Masterswitch (sequence 1-2-1-port-3)', },
+                        {'model': 'APCControl121p1',
+                         'name': 'APC AP79xx or Masterswitch (sequence 1-2-1-port-1)', },
+                        {'model': 'APCControl13p13',
+                         'name': 'APC AP79xx or Masterswitch (sequence 1-3-port-1-3)', },
+
+                        {'model': 'BayTechRPC3NC', 
+                         'name': 'BayTech with prompt RPC3-NC>', },
+                        {'model': 'BayTechRPC16', 
+                         'name': 'BayTech with prompt RPC-16>', },
+                        {'model': 'BayTech',
+                         'name': 'BayTech with prompt DS-RPC>', },
+                        {'model': 'BayTechCtrlC', 
+                         'name': 'BayTech Ctrl-C, 5, then with prompt DS-RPC>', },
+                        {'model': 'BayTechCtrlCUnibe', 
+                         'name': 'BayTech Ctrl-C, 3, then with prompt DS-RPC>', },
+
+                        {'model': 'BlackBoxPSMaverick',
+                         'name': 'BlackBoxPSMaverick Web based controller'},
+
+                        {'model': 'IPAL', 
+                         'name': 'IPAL - Dataprobe IP-41x & IP-81x', },
+                        {'model': 'DRAC',
+                         'name': 'DRAC - Dell RAC Version 3 or 4', },
+                        {'model': 'ePowerSwitchNew',
+                         'name': 'ePowerSwitch Newer Models 1/4/8x', },
+                        {'model': 'ePowerSwitchOld',
+                         'name': 'ePowerSwitch Older Models 1/4/8x', },
+
+                        {'model': 'HPiLO',
+                         'name': 'HP iLO v1 or v2 (Integrated Lights-Out)', },
+
+                        {'model': 'IntelAMT',
+                         'name': 'Intel AMT v2.5 or v3.0 (Active Management Technology)', },
+
+                        {'model': 'IPMI',
+                         'name': 'OpenIPMI - Intelligent Platform Management Interface', },
+
+                        {'model': 'PM211MIP',
+                         'name': 'Infratec PM221-MIP', },
+
+                        {'model': 'WTIIPS4',
+                         'name': 'Western Telematic (WTI IPS-4)', },
+
+                        {'model': 'ManualPCU',
+                         'name': 'Manual Administrator Operation (choose if model unknown)', },
+                         ]
+
+    # Get all model names
+    pcu_models = [type['model'] for type in GetPCUTypes()]
+    for type in pcu_types:
+               if 'pcu_protocol_types' in type:
+               protocol_types = type['pcu_protocol_types']
+               # Take this value out of the struct.
+               del type['pcu_protocol_types']
+               else:
+                       protocol_types = []
+        if type['model'] not in pcu_models:
+            # Add the name/model info into DB
+            id = AddPCUType(type)
+            # for each protocol, also add this.
+            for ptype in protocol_types:
+                AddPCUProtocolType(id, ptype)
+
+    default_boot_states = [
+        'boot',
+        'failboot',
+        'safeboot',
+        'install',
+        'reinstall',
+        'disabled',
+    ]
+    current_boot_states = GetBootStates()
+    for state in default_boot_states:
+        if state not in current_boot_states:
+            AddBootState(state)
+
+    # TODO: Delete old boot states. 
+    # NOTE: Only do this if all federating peers have the new default boot states above.
+    #for state in current_boot_states:
+    #    if state not in default_boot_states:
+    #        DeleteBootState(state)
+
+    # 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()