f36d542e4153357581af00407728295608618b90
[myplc.git] / db-config
1 #!/usr/bin/env /usr/bin/plcsh
2 #
3 # Bootstraps the PLC database with a default administrator account and
4 # a default site, defines default slice attribute types, and
5 # creates/updates default system slices.
6 #
7 # Mark Huang <mlhuang@cs.princeton.edu>
8 # Copyright (C) 2006 The Trustees of Princeton University
9 #
10 # $Id$
11 # $HeadURL$
12
13 from plc_config import PLCConfiguration
14 import sys
15
16 def main():
17     cfg = PLCConfiguration()
18     cfg.load()
19     variables = cfg.variables()
20
21     # Load variables into dictionaries
22     for category_id, (category, variablelist) in variables.iteritems():
23         globals()[category_id] = dict(zip(variablelist.keys(),
24                                        [variable['value'] for variable in variablelist.values()]))
25
26     # Create/update the default administrator account (should be
27     # person_id 2).
28     admin = { 'person_id': 2,
29               'first_name': "Default",
30               'last_name': "Administrator",
31               'email': plc['root_user'],
32               'password': plc['root_password'] }
33     persons = GetPersons([admin['person_id']])
34     if not persons:
35         person_id = AddPerson(admin)
36         if person_id != admin['person_id']:
37             # Huh? Someone deleted the account manually from the database.
38             DeletePerson(person_id)
39             raise Exception, "Someone deleted the \"%s %s\" account from the database!" % \
40                   (admin['first_name'], admin['last_name'])
41         UpdatePerson(person_id, { 'enabled': True })
42     else:
43         person_id = persons[0]['person_id']
44         UpdatePerson(person_id, admin)
45
46     # Create/update the default site (should be site_id 1)
47     if plc_www['port'] == '80':
48         url = "http://" + plc_www['host'] + "/"
49     elif plc_www['port'] == '443':
50         url = "https://" + plc_www['host'] + "/"
51     else:
52         url = "http://" + plc_www['host'] + ":" + plc_www['port'] + "/"
53     site = { 'site_id': 1,
54              'name': plc['name'] + " Central",
55              'abbreviated_name': plc['name'],
56              'login_base': plc['slice_prefix'],
57              'is_public': False,
58              'url': url,
59              'max_slices': 100 }
60
61     sites = GetSites([site['site_id']])
62     if not sites:
63         site_id = AddSite(site['name'], site['abbreviated_name'], site['login_base'], site)
64         if site_id != site['site_id']:
65             DeleteSite(site_id)
66             raise Exception, "Someone deleted the \"%s\" site from the database!" % \
67                   site['name']
68         sites = [site]
69
70     # Must call UpdateSite() even after AddSite() to update max_slices
71     site_id = sites[0]['site_id']
72     UpdateSite(site_id, site)
73
74     # The default administrator account must be associated with a site
75     # in order to login.
76     AddPersonToSite(admin['person_id'], site['site_id'])
77     SetPersonPrimarySite(admin['person_id'], site['site_id'])
78
79     # Grant admin and PI roles to the default administrator account
80     AddRoleToPerson(10, admin['person_id'])
81     AddRoleToPerson(20, admin['person_id'])
82
83     #################### node tags
84     default_tag_types = [
85         { 'tagname' : 'arch',
86           'description' : 'architecture name',
87           'category' : 'general', 
88           'min_role_id' : 40} ,
89         { 'tagname' : 'pldistro',
90           'description' : 'PlanetLab distribution',
91           'category' : 'general', 
92           'min_role_id' : 10} ,
93         { 'tagname' : 'fcdistro',
94           'description' : 'Linux distribution',
95           'category' : 'general', 
96           'min_role_id' : 10} ,
97         { 'tagname' : 'deployment',
98           'description' : 'typically "alpha", "beta", or "production"',
99           'category' : 'general', 
100           'min_role_id' : 10} ,
101         ]
102
103     # Get list of existing tag types
104     known_tag_types = [tag_type['tagname'] for tag_type in GetNodeTagTypes()]
105
106     # Create/update default slice tag types
107     for default_tag_type in default_tag_types:
108         if default_tag_type['tagname'] not in known_tag_types:
109             AddNodeTagType(default_tag_type)
110         else:
111             UpdateNodeTagType(default_tag_type['tagname'], default_tag_type)
112
113     #################### interface settings
114
115     # Setup default slice attribute types
116     default_setting_types = [
117         {'category' : "general",
118          'name' : "ifname",
119          'description': "Set interface name, instead of eth0 or the like",
120          'min_role_id' : 40},
121         {'category' : "Multihome",
122          'name' : "alias",
123          'description': "Specifies that the network is used for multihoming",
124          'min_role_id' : 40},
125
126         {'category' : "hidden",
127          'name' : "backdoor",
128          'description': "For testing new settings",
129          'min_role_id' : 10},
130         ] + [
131         { "category" : "WiFi",
132           "name" : x,
133           "description" : "802.11 %s -- see %s"%(y,z),
134           "min_role_id" : 40 } for (x,y,z) in [
135             ("mode","Mode","iwconfig"),
136             ("essid","ESSID","iwconfig"),
137             ("nw","Network Id","iwconfig"),
138             ("freq","Frequency","iwconfig"),
139             ("channel","Channel","iwconfig"),
140             ("sens","sensitivity threshold","iwconfig"),
141             ("rate","Rate","iwconfig"),
142             ("key","key","iwconfig key"),
143             ("key1","key1","iwconfig key [1]"),
144             ("key2","key2","iwconfig key [2]"),
145             ("key3","key3","iwconfig key [3]"),
146             ("key4","key4","iwconfig key [4]"),
147             ("securitymode","Security mode","iwconfig enc"),
148             ("iwconfig","Additional parameters to iwconfig","ifup-wireless"),
149             ("iwpriv","Additional parameters to iwpriv","ifup-wireless"),
150             ]
151         ]
152
153     # Get list of existing setting types
154     setting_types = GetInterfaceSettingTypes()
155     setting_types = [setting_type['name'] for setting_type in setting_types]
156
157     # Create/update default slice setting types
158     for default_setting_type in default_setting_types:
159         if default_setting_type['name'] not in setting_types:
160             AddInterfaceSettingType(default_setting_type)
161         else:
162             UpdateInterfaceSettingType(default_setting_type['name'], default_setting_type)
163
164     #################### slice attributes
165
166     # Setup default slice attribute types
167     default_attribute_types = [
168         # Slice type (only vserver is supported)
169         {'name': "type",
170          'description': "Type of slice (e.g. vserver)",
171          'min_role_id': 20},
172
173         # System slice
174         {'name': "system",
175          'description': "Is a default system slice (1) or not (0 or unset)",
176          'min_role_id': 10},
177
178         # Slice enabled (1) or suspended (0)
179         {'name': "enabled",
180          'description': "Slice enabled (1 or unset) or suspended (0)",
181          'min_role_id': 10},
182
183         # Slice reference image
184         {'name': "vref",
185          'description': "Reference image",
186          'min_role_id': 30},
187
188         # Slice initialization script
189         {'name': "initscript",
190          'description': "Slice initialization script",
191          'min_role_id': 10},
192
193         # CPU share
194         {'name': "cpu_pct",
195          'description': "Reserved CPU percent",
196          'min_role_id': 10},
197         {'name': "cpu_share",
198          'description': "Number of CPU shares",
199          'min_role_id': 10},
200
201         # Bandwidth limits
202         {'name': "net_min_rate",
203          'description': "Minimum bandwidth (kbps)",
204          'min_role_id': 10},
205         {'name': "net_max_rate",
206          'description': "Maximum bandwidth (kbps)",
207          'min_role_id': 10},
208         {'name': "net_i2_min_rate",
209          'description': "Minimum bandwidth over I2 routes (kbps)",
210          'min_role_id': 10},
211         {'name': "net_i2_max_rate",
212          'description': "Maximum bandwidth over I2 routes (kbps)",
213          'min_role_id': 10},
214         {'name': "net_max_kbyte",
215          'description': "Maximum daily network Tx KByte limit.",
216          'min_role_id': 10},
217         {'name': "net_thresh_kbyte",
218          'description': "KByte limit before warning and throttling.",
219          'min_role_id': 10},
220         {'name': "net_i2_max_kbyte",
221          'description': "Maximum daily network Tx KByte limit to I2 hosts.",
222          'min_role_id': 10},
223         {'name': "net_i2_thresh_kbyte",
224          'description': "KByte limit to I2 hosts before warning and throttling.",
225          'min_role_id': 10},
226         {'name': "net_share",
227          'description': "Number of bandwidth shares",
228          'min_role_id': 10},
229         {'name': "net_i2_share",
230          'description': "Number of bandwidth shares over I2 routes",
231          'min_role_id': 10},
232  
233         # Disk quota
234         {'name': "disk_max",
235          'description': "Disk quota (1k disk blocks)",
236          'min_role_id': 10},
237
238         # Proper operations
239         {'name': "proper_op",
240          'description': "Proper operation (e.g. bind_socket)",
241          'min_role_id': 10},
242
243         # VServer capabilities 
244         {'name': "capabilities",
245          'description': "VServer bcapabilities (separate by commas)",
246          'min_role_id': 10},
247
248                 # Vsys
249         {'name': "vsys",
250          'description': "Bind vsys script fd's to a slice's vsys directory.",
251          'min_role_id': 10},
252
253         # CoDemux
254         {'name': "codemux",
255          'description': "Demux HTTP between slices using localhost ports. Value in the form 'host, localhost port'.",
256          'min_role_id': 10},
257
258         ]
259
260     # Get list of existing attribute types
261     attribute_types = GetSliceAttributeTypes()
262     attribute_types = [attribute_type['name'] for attribute_type in attribute_types]
263
264     # Create/update default slice attribute types
265     for default_attribute_type in default_attribute_types:
266         if default_attribute_type['name'] not in attribute_types:
267             AddSliceAttributeType(default_attribute_type)
268         else:
269             UpdateSliceAttributeType(default_attribute_type['name'], default_attribute_type)
270
271     #################### conf files
272
273     # Setup default PlanetLabConf entries
274     default_conf_files = [
275         # NTP configuration
276         {'enabled': True,
277          'source': 'PlanetLabConf/ntp.conf.php',
278          'dest': '/etc/ntp.conf',
279          'file_permissions': '644',
280          'file_owner': 'root',
281          'file_group': 'root',
282          'preinstall_cmd': '',
283          'postinstall_cmd': '/etc/rc.d/init.d/ntpd restart',
284          'error_cmd': '',
285          'ignore_cmd_errors': False,
286          'always_update': False},
287         {'enabled': True,
288          'source': 'PlanetLabConf/ntp/step-tickers.php',
289          'dest': '/etc/ntp/step-tickers',
290          'file_permissions': '644',
291          'file_owner': 'root',
292          'file_group': 'root',
293          'preinstall_cmd': '',
294          'postinstall_cmd': '/etc/rc.d/init.d/ntpd restart',
295          'error_cmd': '',
296          'ignore_cmd_errors': False,
297          'always_update': False},
298
299         # SSH server configuration
300         {'enabled': True,
301          'source': 'PlanetLabConf/sshd_config',
302          'dest': '/etc/ssh/sshd_config',
303          'file_permissions': '600',
304          'file_owner': 'root',
305          'file_group': 'root',
306          'preinstall_cmd': '',
307          'postinstall_cmd': '/etc/init.d/sshd restart',
308          'error_cmd': '',
309          'ignore_cmd_errors': False,
310          'always_update': False},
311
312         # Administrative SSH keys
313         {'enabled': True,
314          'source': 'PlanetLabConf/keys.php?root',
315          'dest': '/root/.ssh/authorized_keys',
316          'file_permissions': '644',
317          'file_owner': 'root',
318          'file_group': 'root',
319          'preinstall_cmd': '',
320          'postinstall_cmd': '/bin/chmod 700 /root/.ssh',
321          'error_cmd': '',
322          'ignore_cmd_errors': False,
323          'always_update': False},
324         {'enabled': True,
325          'source': 'PlanetLabConf/keys.php?site_admin',
326          'dest': '/home/site_admin/.ssh/authorized_keys',
327          'file_permissions': '644',
328          'file_owner': 'site_admin',
329          'file_group': 'site_admin',
330          'preinstall_cmd': 'grep -q site_admin /etc/passwd',
331          'postinstall_cmd': '/bin/chmod 700 /home/site_admin/.ssh',
332          'error_cmd': '',
333          'ignore_cmd_errors': False,
334          'always_update': False},
335         # Log rotation configuration
336         {'enabled': True,
337          'source': 'PlanetLabConf/logrotate.conf',
338          'dest': '/etc/logrotate.conf',
339          'file_permissions': '644',
340          'file_owner': 'root',
341          'file_group': 'root',
342          'preinstall_cmd': '',
343          'postinstall_cmd': '',
344          'error_cmd': '',
345          'ignore_cmd_errors': False,
346          'always_update': False},
347
348         # updatedb/locate nightly cron job
349         {'enabled': True,
350          'source': 'PlanetLabConf/slocate.cron',
351          'dest': '/etc/cron.daily/slocate.cron',
352          'file_permissions': '755',
353          'file_owner': 'root',
354          'file_group': 'root',
355          'preinstall_cmd': '',
356          'postinstall_cmd': '',
357          'error_cmd': '',
358          'ignore_cmd_errors': False,
359          'always_update': False},
360
361         # YUM configuration
362         {'enabled': True,
363          'source': 'PlanetLabConf/yum.conf.php?gpgcheck=1',
364          'dest': '/etc/yum.conf',
365          'file_permissions': '644',
366          'file_owner': 'root',
367          'file_group': 'root',
368          'preinstall_cmd': '',
369          'postinstall_cmd': '',
370          'error_cmd': '',
371          'ignore_cmd_errors': False,
372          'always_update': False},
373         {'enabled': True,
374          'source': 'PlanetLabConf/delete-rpm-list-production',
375          'dest': '/etc/planetlab/delete-rpm-list',
376          'file_permissions': '644',
377          'file_owner': 'root',
378          'file_group': 'root',
379          'preinstall_cmd': '',
380          'postinstall_cmd': '',
381          'error_cmd': '',
382          'ignore_cmd_errors': False,
383          'always_update': False},
384
385         # PLC configuration
386         {'enabled': True,
387          'source': 'PlanetLabConf/get_plc_config.php',
388          'dest': '/etc/planetlab/plc_config',
389          'file_permissions': '644',
390          'file_owner': 'root',
391          'file_group': 'root',
392          'preinstall_cmd': '',
393          'postinstall_cmd': '',
394          'error_cmd': '',
395          'ignore_cmd_errors': False,
396          'always_update': False},
397         {'enabled': True,
398          'source': 'PlanetLabConf/get_plc_config.php?python',
399          'dest': '/etc/planetlab/plc_config.py',
400          'file_permissions': '644',
401          'file_owner': 'root',
402          'file_group': 'root',
403          'preinstall_cmd': '',
404          'postinstall_cmd': '',
405          'error_cmd': '',
406          'ignore_cmd_errors': False,
407          'always_update': False},
408         {'enabled': True,
409          'source': 'PlanetLabConf/get_plc_config.php?perl',
410          'dest': '/etc/planetlab/plc_config.pl',
411          'file_permissions': '644',
412          'file_owner': 'root',
413          'file_group': 'root',
414          'preinstall_cmd': '',
415          'postinstall_cmd': '',
416          'error_cmd': '',
417          'ignore_cmd_errors': False,
418          'always_update': False},
419         {'enabled': True,
420          'source': 'PlanetLabConf/get_plc_config.php?php',
421          'dest': '/etc/planetlab/php/plc_config.php',
422          'file_permissions': '644',
423          'file_owner': 'root',
424          'file_group': 'root',
425          'preinstall_cmd': '',
426          'postinstall_cmd': '',
427          'error_cmd': '',
428          'ignore_cmd_errors': False,
429          'always_update': False},
430
431         # XXX Required for old Node Manager
432         # Proper configuration
433         {'enabled': True,
434          'source': 'PlanetLabConf/propd.conf',
435          'dest': '/etc/proper/propd.conf',
436          'file_permissions': '644',
437          'file_owner': 'root',
438          'file_group': 'root',
439          'preinstall_cmd': '',
440          'postinstall_cmd': '/etc/init.d/proper restart',
441          'error_cmd': '',
442          'ignore_cmd_errors': True,
443          'always_update': False},
444
445         # XXX Required for old Node Manager
446         # Bandwidth cap
447         {'enabled': True,
448          'source': 'PlanetLabConf/bwlimit.php',
449          'dest': '/etc/planetlab/bwcap',
450          'file_permissions': '644',
451          'file_owner': 'root',
452          'file_group': 'root',
453          'preinstall_cmd': '',
454          'postinstall_cmd': '',
455          'error_cmd': '',
456          'ignore_cmd_errors': True,
457          'always_update': False},
458
459         # Proxy ARP setup
460         {'enabled': True,
461          'source': 'PlanetLabConf/proxies.php',
462          'dest': '/etc/planetlab/proxies',
463          'file_permissions': '644',
464          'file_owner': 'root',
465          'file_group': 'root',
466          'preinstall_cmd': '',
467          'postinstall_cmd': '',
468          'error_cmd': '',
469          'ignore_cmd_errors': False,
470          'always_update': False},
471
472         # Firewall configuration
473         {'enabled': True,
474          'source': 'PlanetLabConf/iptables',
475          'dest': '/etc/sysconfig/iptables',
476          'file_permissions': '600',
477          'file_owner': 'root',
478          'file_group': 'root',
479          'preinstall_cmd': '',
480          'postinstall_cmd': '',
481          'error_cmd': '',
482          'ignore_cmd_errors': False,
483          'always_update': False},
484         {'enabled': True,
485          'source': 'PlanetLabConf/blacklist.php',
486          'dest': '/etc/planetlab/blacklist',
487          'file_permissions': '600',
488          'file_owner': 'root',
489          'file_group': 'root',
490          'preinstall_cmd': '',
491          'postinstall_cmd': '/sbin/iptables-restore --noflush < /etc/planetlab/blacklist',
492          'error_cmd': '',
493          'ignore_cmd_errors': True,
494          'always_update': False},
495
496         # /etc/issue
497         {'enabled': True,
498          'source': 'PlanetLabConf/issue.php',
499          'dest': '/etc/issue',
500          'file_permissions': '644',
501          'file_owner': 'root',
502          'file_group': 'root',
503          'preinstall_cmd': '',
504          'postinstall_cmd': '',
505          'error_cmd': '',
506          'ignore_cmd_errors': False,
507          'always_update': False},
508
509         # Kernel parameters
510         {'enabled': True,
511          'source': 'PlanetLabConf/sysctl.php',
512          'dest': '/etc/sysctl.conf',
513          'file_permissions': '644',
514          'file_owner': 'root',
515          'file_group': 'root',
516          'preinstall_cmd': '',
517          'postinstall_cmd': '/sbin/sysctl -e -p /etc/sysctl.conf',
518          'error_cmd': '',
519          'ignore_cmd_errors': False,
520          'always_update': False},
521
522         # Sendmail configuration
523         {'enabled': True,
524          'source': 'PlanetLabConf/sendmail.mc',
525          'dest': '/etc/mail/sendmail.mc',
526          'file_permissions': '644',
527          'file_owner': 'root',
528          'file_group': 'root',
529          'preinstall_cmd': '',
530          'postinstall_cmd': '',
531          'error_cmd': '',
532          'ignore_cmd_errors': False,
533          'always_update': False},
534         {'enabled': True,
535          'source': 'PlanetLabConf/sendmail.cf',
536          'dest': '/etc/mail/sendmail.cf',
537          'file_permissions': '644',
538          'file_owner': 'root',
539          'file_group': 'root',
540          'preinstall_cmd': '',
541          'postinstall_cmd': 'service sendmail restart',
542          'error_cmd': '',
543          'ignore_cmd_errors': False,
544          'always_update': False},
545
546         # GPG signing keys
547         {'enabled': True,
548          'source': 'PlanetLabConf/RPM-GPG-KEY-fedora',
549          'dest': '/etc/pki/rpm-gpg/RPM-GPG-KEY-fedora',
550          'file_permissions': '644',
551          'file_owner': 'root',
552          'file_group': 'root',
553          'preinstall_cmd': '',
554          'postinstall_cmd': 'rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora',
555          'error_cmd': '',
556          'ignore_cmd_errors': False,
557          'always_update': False},
558         {'enabled': True,
559          'source': 'PlanetLabConf/get_gpg_key.php',
560          'dest': '/etc/pki/rpm-gpg/RPM-GPG-KEY-planetlab',
561          'file_permissions': '644',
562          'file_owner': 'root',
563          'file_group': 'root',
564          'preinstall_cmd': '',
565          'postinstall_cmd': 'rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-planetlab',
566          'error_cmd': '',
567          'ignore_cmd_errors': False,
568          'always_update': False},
569
570         # Ping of death configuration
571         # the 'restart' postcommand doesn't work, b/c the pod script doesn't support it.
572         {'enabled': True,
573          'source': 'PlanetLabConf/ipod.conf.php',
574          'dest': '/etc/ipod.conf',
575          'file_permissions': '644',
576          'file_owner': 'root',
577          'file_group': 'root',
578          'preinstall_cmd': '',
579          'postinstall_cmd': '/etc/init.d/pod start',
580          'error_cmd': '',
581          'ignore_cmd_errors': False,
582          'always_update': False},
583
584         # sudo configuration
585         {'enabled': True,
586          'source': 'PlanetLabConf/sudoers.php',
587          'dest': '/etc/sudoers',
588          'file_permissions': '440',
589          'file_owner': 'root',
590          'file_group': 'root',
591          'preinstall_cmd': '',
592          'postinstall_cmd': '/usr/sbin/visudo -c',
593          'error_cmd': '',
594          'ignore_cmd_errors': False,
595          'always_update': False}
596         ]
597
598     # Get list of existing (enabled, global) files
599     conf_files = GetConfFiles()
600     conf_files = filter(lambda conf_file: conf_file['enabled'] and \
601                                           not conf_file['node_ids'] and \
602                                           not conf_file['nodegroup_ids'],
603                         conf_files)
604     dests = [conf_file['dest'] for conf_file in conf_files]
605     conf_files = dict(zip(dests, conf_files))
606
607     # Create/update default PlanetLabConf entries
608     for default_conf_file in default_conf_files:
609         if default_conf_file['dest'] not in dests:
610             AddConfFile(default_conf_file)
611         else:
612             conf_file = conf_files[default_conf_file['dest']]
613             UpdateConfFile(conf_file['conf_file_id'], default_conf_file)
614
615
616     #################### initscripts
617
618     # Default Initscripts
619     default_initscripts = []
620
621     # Find initscripts and add them to the db
622     for (root, dirs, files) in os.walk("/etc/plc_sliceinitscripts"):
623         for f in files:
624             # Read the file
625             file = open(root + "/" + f, "ro")
626             default_initscripts.append({"name": plc['slice_prefix'] + "_" + f,
627                                         "enabled": True,
628                                         "script": file.read().replace("@SITE@", url).replace("@PREFIX@", plc['slice_prefix'])})
629             file.close()
630
631     # Get list of existing initscripts
632     oldinitscripts = GetInitScripts()
633     oldinitscripts = [script['name'] for script in oldinitscripts]
634
635     for initscript in default_initscripts:
636         if initscript['name'] not in oldinitscripts:  AddInitScript(initscript)
637
638     # Create/update system slices
639     default_slices = [
640          # PlanetFlow
641         {'name': plc['slice_prefix'] + "_netflow",
642          '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.",
643          'url': url,
644          'instantiation': "plc-instantiated",
645          # Renew forever (minus one day, work around date conversion weirdness)
646          'expires': 0x7fffffff - (60 * 60 * 24),
647          'attributes': [('system', "1"),
648                         ('vref', "planetflow"),
649                                                 ('vsys', "pfmount")]},
650           # Sirius
651         {'name': plc['slice_prefix'] + "_sirius",
652          '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',
653          'url': url + "db/sirius/index.php",
654          'instantiation': "plc-instantiated",
655          # Renew forever (minus one day, work around date conversion weirdness)
656          'expires': 0x7fffffff - (60 * 60 * 24),
657          'attributes': [('system', "1"),
658                         ('net_min_rate', "2000"),
659                         ('cpu_pct', "25"),
660                         ('initscript', plc['slice_prefix'] + "_sirius")]}
661         ]
662     
663     for default_slice in default_slices:
664         slices = GetSlices([default_slice['name']])
665         if slices:
666             slice = slices[0]
667             UpdateSlice(slice['slice_id'], default_slice)
668         else:
669             AddSlice(default_slice)
670             slice = GetSlices([default_slice['name']])[0]
671
672         # Create/update all attributes
673         slice_attributes = []
674         if slice['slice_attribute_ids']:
675             # Delete unknown attributes
676             for slice_attribute in GetSliceAttributes(slice['slice_attribute_ids']):
677                 if (slice_attribute['name'], slice_attribute['value']) \
678                    not in default_slice['attributes']:
679                     DeleteSliceAttribute(slice_attribute['slice_attribute_id'])
680                 else:
681                     slice_attributes.append((slice_attribute['name'], slice_attribute['value']))
682
683         for (name, value) in default_slice['attributes']:
684             if (name, value) not in slice_attributes:
685                 AddSliceAttribute(slice['name'], name, value)
686
687     
688     #################### body for messages
689
690     installfailed = """
691 Once the node meets these requirements, please reinitiate the install
692 by visiting:
693
694 https://%(PLC_WWW_HOST)s:%(PLC_WWW_SSL_PORT)d/db/nodes/?id=%(node_id)d
695
696 Update the BootState to 'Reinstall', then reboot the node.
697
698 If you have already performed this step and are still receiving this
699 message, please reply so that we may investigate the problem.
700 """
701
702     # Load default message templates
703     message_templates = [
704         {'message_id': 'Verify account',
705          'subject': "Verify account registration",
706          'template': """
707 Please verify that you registered for a %(PLC_NAME)s account with the
708 username %(email)s by visiting:
709
710 https://%(PLC_WWW_HOST)s:%(PLC_WWW_SSL_PORT)d/db/persons/register.php?id=%(person_id)d&key=%(verification_key)s
711
712 If you did not register for a %(PLC_NAME)s account, please ignore this
713 message, or contact %(PLC_NAME)s Support <%(PLC_MAIL_SUPPORT_ADDRESS)s>.
714 """
715          },
716
717         {'message_id': 'New PI account',
718          'subject': "New PI account registration from %(first_name)s %(last_name)s <%(email)s> at %(site_name)s",
719          'template': """
720 %(first_name)s %(last_name)s <%(email)s> has signed up for a new
721 %(PLC_NAME)s account at %(site_name)s and has requested a PI role. PIs
722 are responsible for enabling user accounts, creating slices, and
723 ensuring that all users abide by the %(PLC_NAME)s Acceptable Use
724 Policy.
725
726 Only %(PLC_NAME)s administrators may enable new PI accounts. If you
727 are a PI at %(site_name)s, please respond and indicate whether this
728 registration is acceptable.
729
730 To view the request, visit:
731
732 https://%(PLC_WWW_HOST)s:%(PLC_WWW_SSL_PORT)d/db/persons/index.php?id=%(person_id)d
733 """
734          },
735
736         {'message_id': 'New account',
737          'subject': "New account registration from %(first_name)s %(last_name)s <%(email)s> at %(site_name)s",
738          'template': """
739 %(first_name)s %(last_name)s <%(email)s> has signed up for a new
740 %(PLC_NAME)s account at %(site_name)s and has requested the following
741 roles: %(roles)s.
742
743 To deny the request or enable the account, visit:
744
745 https://%(PLC_WWW_HOST)s:%(PLC_WWW_SSL_PORT)d/db/persons/index.php?id=%(person_id)d
746 """
747          },
748
749         {'message_id': 'Password reset requested',
750          'subject': "Password reset requested",
751          'template': """
752 Someone has requested that the password of your %(PLC_NAME)s account
753 %(email)s be reset. If this person was you, you may continue with the
754 reset by visiting:
755
756 https://%(PLC_WWW_HOST)s:%(PLC_WWW_SSL_PORT)d/db/persons/reset_password.php?id=%(person_id)d&key=%(verification_key)s
757
758 If you did not request that your password be reset, please contact
759 %(PLC_NAME)s Support <%(PLC_MAIL_SUPPORT_ADDRESS)s>. Do not quote or
760 otherwise include any of this text in any correspondence.
761 """
762          },
763
764         {'message_id': 'Password reset',
765          'subject': "Password reset",
766          'template': """
767 The password of your %(PLC_NAME)s account %(email)s has been
768 temporarily reset to:
769
770 %(password)s
771
772 Please change it at as soon as possible by visiting:
773
774 https://%(PLC_WWW_HOST)s:%(PLC_WWW_SSL_PORT)d/db/persons/index.php?id=%(person_id)d
775
776 If you did not request that your password be reset, please contact
777 %(PLC_NAME)s Support <%(PLC_MAIL_SUPPORT_ADDRESS)s>. Do not quote or
778 otherwise include any of this text in any correspondence.
779 """
780          },
781
782         # Boot Manager messages
783         {'message_id': "installfinished",
784          'subject': "%(hostname)s completed installation",
785          'template': """
786 %(hostname)s just completed installation.
787
788 The node should be usable in a couple of minutes if installation was
789 successful.
790 """
791          },
792
793         {'message_id': "insufficientdisk",
794          'subject': "%(hostname)s does not have sufficient disk space",
795          'template': """
796 %(hostname)s failed to boot because it does not have sufficent disk
797 space, or because its disk controller was not recognized.
798
799 Please replace the current disk or disk controller or install
800 additional disks to meet the current hardware requirements.
801 """ + installfailed
802          },
803
804         {'message_id': "insufficientmemory",
805          'subject': "%(hostname)s does not have sufficient memory",
806          'template': """
807 %(hostname)s failed to boot because it does not have sufficent
808 memory.
809
810 Please install additional memory to meet the current hardware
811 requirements.
812 """ + installfailed
813          },
814
815         {'message_id': "authfail",
816          'subject': "%(hostname)s failed to authenticate",
817          'template':
818 """
819 %(hostname)s failed to authenticate for the following reason:
820
821 %(fault)s
822
823 The most common reason for authentication failure is that the
824 authentication key stored in the node configuration file, does not
825 match the key on record. 
826
827 There are two possible steps to resolve the problem.
828
829 1. If you have used an All-in-one BootCD that includes the plnode.txt file,
830     then please check your machine for any old boot media, either in the
831     floppy drive, or on a USB stick.  It is likely that an old configuration
832     is being used instead of the new configuration stored on the BootCD.
833 Or, 
834 2. If you are using Generic BootCD image, then regenerate the node 
835     configuration file by visiting:
836
837     https://%(PLC_WWW_HOST)s:%(PLC_WWW_SSL_PORT)d/db/nodes/?id=%(node_id)d
838
839     Under 'Download', follow the 'Download plnode.txt file for %(hostname)s'
840     option, and save the downloaded file as plnode.txt on either a floppy 
841     disk or a USB flash drive.  Be sure the 'Boot State' is set to 'Boot', 
842     and, then reboot the node.
843
844 If you have already performed this step and are still receiving this
845 message, please reply so that we can help investigate the problem.
846 """
847          },
848
849         {'message_id': "notinstalled",
850          'subject': "%(hostname)s is not installed",
851          'template':
852 """
853 %(hostname)s failed to boot because it has either never been
854 installed, or the installation is corrupt.
855
856 Please check if the hard drive has failed, and replace it if so. After
857 doing so, visit:
858
859 https://%(PLC_WWW_HOST)s:%(PLC_WWW_SSL_PORT)d/db/nodes/?id=%(node_id)d
860
861 Change the 'Boot State' to 'Reinstall', and then reboot the node.
862
863 If you have already performed this step and are still receiving this
864 message, please reply so that we may investigate the problem.
865 """
866          },
867
868         {'message_id': "hostnamenotresolve",
869          'subject': "%(hostname)s does not resolve",
870          'template':
871 """
872 %(hostname)s failed to boot because its hostname does not resolve, or
873 does resolve but does not match its configured IP address.
874
875 Please check the network settings for the node, especially its
876 hostname, IP address, and DNS servers, by visiting:
877
878 https://%(PLC_WWW_HOST)s:%(PLC_WWW_SSL_PORT)d/db/nodes/?id=%(node_id)d
879
880 Correct any errors, and change the 'Boot State' to 'Reinstall', and then
881 reboot the node.
882
883 If you have already performed this step and are still receiving this
884 message, please reply so that we may investigate the problem.
885 """
886          },
887
888         # XXX N.B. I don't think these are necessary, since there's no
889         # way that the Boot Manager would even be able to contact the
890         # API to send these messages.
891
892         {'message_id': "noconfig",
893          'subject': "%(hostname)s does not have a configuration file",
894          'template': """
895 %(hostname)s failed to boot because it could not find a PlanetLab
896 configuration file. To create this file, visit:
897
898 https://%(PLC_WWW_HOST)s:%(PLC_WWW_SSL_PORT)d/db/nodes/?id=%(node_id)d
899
900 Click the Configuration File link, and save the downloaded file as
901 plnode.txt on either a floppy disk or a USB flash drive.  Change the 
902 'Boot State' to 'Reinstall', and then reboot the node.
903
904 If you have already performed this step and are still receiving this
905 message, please reply so that we may investigate the problem.
906 """
907          },
908
909         {'message_id': "nodetectednetwork",
910          'subject': "%(hostname)s has unsupported network hardware",
911          'template':
912 """
913
914 %(hostname)s failed to boot because it has network hardware that is
915 unsupported by the current production kernel. If it has booted
916 successfully in the past, please try re-installing it by visiting:
917
918 https://%(PLC_WWW_HOST)s:%(PLC_WWW_SSL_PORT)d/db/nodes/?id=%(node_id)d
919
920 Change the 'Boot State' to 'Reinstall', and then reboot the node.
921
922 If you have already performed this step and are still receiving this
923 message, please reply so that we may investigate the problem.
924 """
925          },
926         ]
927
928     for template in message_templates:
929         messages = GetMessages([template['message_id']])
930         if not messages:
931             AddMessage(template)
932
933     #################### PCUs
934     
935     ### Setup Initial PCU information
936     pcu_types = [{'model': 'AP79xx',
937           'name': 'APC AP79xx',
938           'pcu_protocol_types': [{ 'port': 80,
939                                   'protocol': 'APC79xxHttp',
940                                   'supported': False},
941                                  { 'port': 23,
942                                   'protocol': 'APC79xx',
943                                   'supported': True},
944                                  { 'port': 22,
945                                   'protocol': 'APC79xx',
946                                   'supported': True}],
947           },
948          {'model': 'Masterswitch',
949           'name': 'APC Masterswitch',
950           'pcu_protocol_types': [{ 'port': 80,
951                                   'protocol': 'APCMasterHttp',
952                                   'supported': False},
953                                  { 'port': 23,
954                                   'protocol': 'APCMaster',
955                                   'supported': True},
956                                  { 'port': 22,
957                                   'protocol': 'APCMaster',
958                                   'supported': True}],
959           },
960          {'model': 'DS4-RPC',
961           'name': 'BayTech DS4-RPC',
962           'pcu_protocol_types': [{ 'port': 80,
963                                   'protocol': 'BayTechHttp',
964                                   'supported': False},
965                                  { 'port': 23,
966                                   'protocol': 'BayTech',
967                                   'supported': True},
968                                  { 'port': 22,
969                                   'protocol': 'BayTech',
970                                   'supported': True}],
971           },
972          {'model': 'IP-41x_IP-81x',
973           'name': 'Dataprobe IP-41x & IP-81x',
974           'pcu_protocol_types': [ { 'port': 23,
975                                   'protocol': 'IPALTelnet',
976                                   'supported': True},
977                                   { 'port': 80,
978                                   'protocol': 'IPALHttp',
979                                   'supported': False}],
980           },
981          {'model': 'DRAC3',
982           'name': 'Dell RAC Version 3',
983           'pcu_protocol_types': [],
984           },
985          {'model': 'DRAC4',
986           'name': 'Dell RAC Version 4',
987           'pcu_protocol_types': [{ 'port': 443,
988                                   'protocol': 'DRACRacAdm',
989                                   'supported': True},
990                                  { 'port': 80,
991                                   'protocol': 'DRACRacAdm',
992                                   'supported': False},
993                                  { 'port': 22,
994                                   'protocol': 'DRAC',
995                                   'supported': True}],
996           },
997          {'model': 'ePowerSwitch',
998           'name': 'ePowerSwitch 1/4/8x',
999           'pcu_protocol_types': [{ 'port': 80,
1000                                   'protocol': 'ePowerSwitch',
1001                                   'supported': True}],
1002           },
1003          {'model': 'ilo2',
1004           'name': 'HP iLO2 (Integrated Lights-Out)',
1005           'pcu_protocol_types': [{ 'port': 443,
1006                                   'protocol': 'HPiLOHttps',
1007                                   'supported': True},
1008                                  { 'port': 22,
1009                                   'protocol': 'HPiLO',
1010                                   'supported': True}],
1011           },
1012          {'model': 'ilo1',
1013           'name': 'HP iLO version 1',
1014           'pcu_protocol_types': [],
1015           },
1016          {'model': 'PM211-MIP',
1017           'name': 'Infratec PM221-MIP',
1018           'pcu_protocol_types': [],
1019           },
1020          {'model': 'AMT2.5',
1021           'name': 'Intel AMT v2.5 (Active Management Technology)',
1022           'pcu_protocol_types': [],
1023           },
1024          {'model': 'AMT3.0',
1025           'name': 'Intel AMT v3.0 (Active Management Technology)',
1026           'pcu_protocol_types': [],
1027           },
1028          {'model': 'WTI_IPS-4',
1029           'name': 'Western Telematic (WTI IPS-4)',
1030           'pcu_protocol_types': [],
1031           },
1032          {'model': 'unknown',
1033           'name': 'Unknown Vendor or Model',
1034           'pcu_protocol_types': [{ 'port': 443,
1035                                   'protocol': 'UnknownPCU',
1036                                   'supported': False},
1037                                  { 'port': 80,
1038                                   'protocol': 'UnknownPCU',
1039                                   'supported': False},
1040                                  { 'port': 23,
1041                                   'protocol': 'UnknownPCU',
1042                                   'supported': False},
1043                                  { 'port': 22,
1044                                   'protocol': 'UnknownPCU',
1045                                   'supported': False}],
1046           }]
1047
1048     # Get all model names
1049     pcu_models = [type['model'] for type in GetPCUTypes()]
1050     for type in pcu_types:
1051         protocol_types = type['pcu_protocol_types']
1052         # Take this value out of the struct.
1053         del type['pcu_protocol_types']
1054         if type['model'] not in pcu_models:
1055             # Add the name/model info into DB
1056             id = AddPCUType(type)
1057             # for each protocol, also add this.
1058             for ptype in protocol_types:
1059                 AddPCUProtocolType(id, ptype)
1060
1061
1062 if __name__ == '__main__':
1063     main()
1064
1065 # Local variables:
1066 # tab-width: 4
1067 # mode: python
1068 # End: