- write all nodes' IP addresses into /etc/hosts in preparation for
[myplc.git] / api-config
1 #!/usr/bin/python
2 #
3 # Bootstraps the PLC database with a default administrator account and
4 # a default site.
5 #
6 # Mark Huang <mlhuang@cs.princeton.edu>
7 # Copyright (C) 2006 The Trustees of Princeton University
8 #
9 # $Id: api-config,v 1.7 2006/05/09 19:52:01 mlhuang Exp $
10 #
11
12 import plcapilib
13 (plcapi, moreopts, argv) = plcapilib.plcapi(globals())
14 from plc_config import PLCConfiguration
15 import sys
16
17
18 def main():
19     cfg = PLCConfiguration()
20     cfg.load()
21     variables = cfg.variables()
22
23     # Load variables into dictionaries
24     (category, variablelist) = variables['plc']
25     plc = dict(zip(variablelist.keys(),
26                    [variable['value'] for variable in variablelist.values()]))
27
28     (category, variablelist) = variables['plc_www']
29     plc_www = dict(zip(variablelist.keys(),
30                        [variable['value'] for variable in variablelist.values()]))
31
32     (category, variablelist) = variables['plc_api']
33     plc_api = dict(zip(variablelist.keys(),
34                        [variable['value'] for variable in variablelist.values()]))
35
36     # Create/update the default administrator account (should be
37     # person_id 2).
38     admin = { 'person_id': 2,
39               'first_name': "Default",
40               'last_name': "Administrator",
41               'email': plc['root_user'],
42               'password': plc['root_password'] }
43     persons = AdmGetPersons([admin['person_id']])
44     if not persons:
45         person_id = AdmAddPerson(admin['first_name'], admin['last_name'], admin)
46         if person_id != admin['person_id']:
47             # Huh? Someone deleted the account manually from the database.
48             AdmDeletePerson(person_id)
49             raise Exception, "Someone deleted the \"%s %s\" account from the database!" % \
50                   (admin['first_name'], admin['last_name'])
51         AdmSetPersonEnabled(person_id, True)
52     else:
53         person_id = persons[0]['person_id']
54         AdmUpdatePerson(person_id, admin)
55
56     # Create/update the default site (should be site_id 1)
57     if plc_www['port'] == '80':
58         url = "http://" + plc_www['host'] + "/"
59     elif plc_www['port'] == '443':
60         url = "https://" + plc_www['host'] + "/"
61     else:
62         url = "http://" + plc_www['host'] + ":" + plc_www['port'] + "/"
63     site = { 'site_id': 1,
64              'name': plc['name'] + " Central",
65              'abbreviated_name': plc['name'],
66              # XXX Default site slice_prefix/login_base must be "pl_"
67              # 'login_base': plc['slice_prefix'],
68              'login_base': "pl",
69              'is_public': False,
70              'url': url,
71              'max_slices': 100 }
72
73     sites = AdmGetSites([site['site_id']])
74     if not sites:
75         site_id = AdmAddSite(site['name'], site['abbreviated_name'], site['login_base'], site)
76         if site_id != site['site_id']:
77             AdmDeleteSite(site_id)
78             raise Exception, "Someone deleted the \"%s\" site from the database!" % \
79                   site['name']
80         sites = [site]
81
82     # Must call AdmUpdateSite() even after AdmAddSite() to update max_slices
83     site_id = sites[0]['site_id']
84     # XXX login_base cannot be updated
85     del site['login_base']
86     AdmUpdateSite(site_id, site)
87
88     # The default administrator account must be associated with a site
89     # in order to login.
90     AdmAddPersonToSite(admin['person_id'], site['site_id'])
91     AdmSetPersonPrimarySite(admin['person_id'], site['site_id'])
92
93     # Grant admin and PI roles to the default administrator account
94     AdmGrantRoleToPerson(admin['person_id'], 10)
95     AdmGrantRoleToPerson(admin['person_id'], 20)
96
97     # Read and parse /etc/hosts
98     hosts = {}
99     for line in file("/etc/hosts"):
100         line = line.strip()
101         words = line.split()
102         if len(words) > 1 and words[0] != "#":
103             hosts[words[0]] = words[1:]
104
105     nodes = AdmGetNodes([], ['node_id', 'hostname'])
106
107     # Get the primary IP address for each node
108     plcapi.begin()
109     for node in nodes:
110         AdmGetAllNodeNetworks(node['node_id'])
111     nodenetworks_list = plcapi.commit()
112     for i, nodenetworks in enumerate(nodenetworks_list):
113         for nodenetwork in nodenetworks:
114             if nodenetwork['hostname']:
115                 hostname = nodenetwork['hostname']
116             else:
117                 hostname = nodes[i]['hostname']
118
119             if hosts.has_key(nodenetwork['ip']):
120                 if hostname not in hosts[nodenetwork['ip']]:
121                     hosts[nodenetwork['ip']].append(hostname)
122             else:
123                 hosts[nodenetwork['ip']] = [hostname]
124     
125     # Rewrite /etc/hosts
126     etc_hosts = open("/etc/hosts", "w")
127     for ip, hostnames in hosts.iteritems():
128         etc_hosts.write(ip + "\t" + " ".join(hostnames) + "\n")
129     etc_hosts.close()
130
131     # Setup default PlanetLabConf entries
132     default_conf_files = [
133         # NTP configuration
134         {'enabled': 1,
135          'source': 'PlanetLabConf/ntpconf.php',
136          'dest': '/etc/ntp.conf',
137          'file_permissions': '644',
138          'file_owner': 'root',
139          'file_group': 'root',
140          'preinstall_cmd': '',
141          'postinstall_cmd': '/etc/rc.d/init.d/ntpd restart',
142          'error_cmd': '',
143          'ignore_cmd_errors': 0,
144          'always_update': 0},
145         {'enabled': 1,
146          'source': 'PlanetLabConf/ntptickers.php',
147          'dest': '/etc/ntp/step-tickers',
148          'file_permissions': '644',
149          'file_owner': 'root',
150          'file_group': 'root',
151          'preinstall_cmd': '',
152          'postinstall_cmd': '/etc/rc.d/init.d/ntpd restart',
153          'error_cmd': '',
154          'ignore_cmd_errors': 0,
155          'always_update': 0},
156
157         # SSH server configuration
158         {'enabled': 1,
159          'source': 'PlanetLabConf/sshd_config',
160          'dest': '/etc/ssh/sshd_config',
161          'file_permissions': '600',
162          'file_owner': 'root',
163          'file_group': 'root',
164          'preinstall_cmd': '',
165          'postinstall_cmd': '/etc/init.d/sshd restart',
166          'error_cmd': '',
167          'ignore_cmd_errors': 0,
168          'always_update': 0},
169
170         # Administrative SSH keys
171         {'enabled': 1,
172          'source': 'PlanetLabConf/keys.php?root',
173          'dest': '/root/.ssh/authorized_keys',
174          'file_permissions': '644',
175          'file_owner': 'root',
176          'file_group': 'root',
177          'preinstall_cmd': '',
178          'postinstall_cmd': '',
179          'error_cmd': '',
180          'ignore_cmd_errors': 0,
181          'always_update': 0},
182         {'enabled': 1,
183          'source': 'PlanetLabConf/keys.php?site_admin',
184          'dest': '/home/site_admin/.ssh/authorized_keys',
185          'file_permissions': '644',
186          'file_owner': 'site_admin',
187          'file_group': 'site_admin',
188          'preinstall_cmd': 'grep -q site_admin /etc/passwd',
189          'postinstall_cmd': '',
190          'error_cmd': '',
191          'ignore_cmd_errors': 0,
192          'always_update': 0},
193         {'enabled': 1,
194          'source': 'PlanetLabConf/keys.php?role=admin',
195          'dest': '/home/pl_admin/.ssh/authorized_keys',
196          'file_permissions': '644',
197          'file_owner': 'pl_admin',
198          'file_group': 'pl_admin',
199          'preinstall_cmd': 'grep -q pl_admin /etc/passwd',
200          'postinstall_cmd': '',
201          'error_cmd': '',
202          'ignore_cmd_errors': 0,
203          'always_update': 0},
204
205         # Log rotation configuration
206         {'enabled': 1,
207          'source': 'PlanetLabConf/logrotate.conf',
208          'dest': '/etc/logrotate.conf',
209          'file_permissions': '644',
210          'file_owner': 'root',
211          'file_group': 'root',
212          'preinstall_cmd': '',
213          'postinstall_cmd': '',
214          'error_cmd': '',
215          'ignore_cmd_errors': 0,
216          'always_update': 0},
217
218         # updatedb/locate nightly cron job
219         {'enabled': 1,
220          'source': 'PlanetLabConf/slocate.cron',
221          'dest': '/etc/cron.daily/slocate.cron',
222          'file_permissions': '755',
223          'file_owner': 'root',
224          'file_group': 'root',
225          'preinstall_cmd': '',
226          'postinstall_cmd': '',
227          'error_cmd': '',
228          'ignore_cmd_errors': 0,
229          'always_update': 0},
230
231         # YUM configuration
232         {'enabled': 1,
233          'source': 'PlanetLabConf/yum.conf.php?gpgcheck=1',
234          'dest': '/etc/yum.conf',
235          'file_permissions': '644',
236          'file_owner': 'root',
237          'file_group': 'root',
238          'preinstall_cmd': '',
239          'postinstall_cmd': '',
240          'error_cmd': '',
241          'ignore_cmd_errors': 0,
242          'always_update': 0},
243         {'enabled': 1,
244          'source': 'PlanetLabConf/delete-rpm-list-production',
245          'dest': '/etc/planetlab/delete-rpm-list',
246          'file_permissions': '644',
247          'file_owner': 'root',
248          'file_group': 'root',
249          'preinstall_cmd': '',
250          'postinstall_cmd': '',
251          'error_cmd': '',
252          'ignore_cmd_errors': 0,
253          'always_update': 0},
254
255         # PLC configuration
256         {'enabled': 1,
257          'source': 'PlanetLabConf/get_plc_config.php',
258          'dest': '/etc/planetlab/plc_config',
259          'file_permissions': '644',
260          'file_owner': 'root',
261          'file_group': 'root',
262          'preinstall_cmd': '',
263          'postinstall_cmd': '',
264          'error_cmd': '',
265          'ignore_cmd_errors': 0,
266          'always_update': 0},
267         {'enabled': 1,
268          'source': 'PlanetLabConf/get_plc_config.php?python',
269          'dest': '/etc/planetlab/plc_config.py',
270          'file_permissions': '644',
271          'file_owner': 'root',
272          'file_group': 'root',
273          'preinstall_cmd': '',
274          'postinstall_cmd': '',
275          'error_cmd': '',
276          'ignore_cmd_errors': 0,
277          'always_update': 0},
278         {'enabled': 1,
279          'source': 'PlanetLabConf/get_plc_config.php?perl',
280          'dest': '/etc/planetlab/plc_config.pl',
281          'file_permissions': '644',
282          'file_owner': 'root',
283          'file_group': 'root',
284          'preinstall_cmd': '',
285          'postinstall_cmd': '',
286          'error_cmd': '',
287          'ignore_cmd_errors': 0,
288          'always_update': 0},
289         {'enabled': 1,
290          'source': 'PlanetLabConf/get_plc_config.php?php',
291          'dest': '/etc/planetlab/php/plc_config.php',
292          'file_permissions': '644',
293          'file_owner': 'root',
294          'file_group': 'root',
295          'preinstall_cmd': '',
296          'postinstall_cmd': '',
297          'error_cmd': '',
298          'ignore_cmd_errors': 0,
299          'always_update': 0},
300
301         # Node Manager configuration
302         {'enabled': 1,
303          'source': 'PlanetLabConf/pl_nm-v3.conf',
304          'dest': '/etc/planetlab/pl_nm.conf',
305          'file_permissions': '644',
306          'file_owner': 'root',
307          'file_group': 'root',
308          'preinstall_cmd': '',
309          'postinstall_cmd': '/etc/init.d/pl_nm restart',
310          'error_cmd': '',
311          'ignore_cmd_errors': 0,
312          'always_update': 0},
313         {'enabled': 1,
314          'source': 'PlanetLabConf/RootResources/plc_slice_pool.php',
315          'dest': '/home/pl_nm/RootResources/plc_slice_pool',
316          'file_permissions': '644',
317          'file_owner': 'pl_nm',
318          'file_group': 'pl_nm',
319          'preinstall_cmd': '',
320          'postinstall_cmd': '',
321          'error_cmd': '',
322          'ignore_cmd_errors': 0,
323          'always_update': 0},
324         {'enabled': 1,
325          'source': 'PlanetLabConf/RootResources/pl_conf.py',
326          'dest': '/home/pl_nm/RootResources/pl_conf',
327          'file_permissions': '644',
328          'file_owner': 'pl_nm',
329          'file_group': 'pl_nm',
330          'preinstall_cmd': '',
331          'postinstall_cmd': '/etc/init.d/pl_nm restart',
332          'error_cmd': '',
333          'ignore_cmd_errors': 0,
334          'always_update': 0},
335         {'enabled': 1,
336          'source': 'PlanetLabConf/RootResources/pl_netflow.py',
337          'dest': '/home/pl_nm/RootResources/pl_netflow',
338          'file_permissions': '644',
339          'file_owner': 'pl_nm',
340          'file_group': 'pl_nm',
341          'preinstall_cmd': '',
342          'postinstall_cmd': '',
343          'error_cmd': '',
344          'ignore_cmd_errors': 0,
345          'always_update': 0},
346
347         # Proper configuration
348         {'enabled': 1,
349          'source': 'PlanetLabConf/propd-NM-1.0.conf',
350          'dest': '/etc/proper/propd.conf',
351          'file_permissions': '644',
352          'file_owner': 'root',
353          'file_group': 'root',
354          'preinstall_cmd': '',
355          'postinstall_cmd': '/etc/init.d/proper restart',
356          'error_cmd': '',
357          'ignore_cmd_errors': 1,
358          'always_update': 0},
359
360         # Bandwidth cap
361         {'enabled': 1,
362          'source': 'PlanetLabConf/bwlimit.php',
363          'dest': '/etc/planetlab/bwcap',
364          'file_permissions': '644',
365          'file_owner': 'root',
366          'file_group': 'root',
367          'preinstall_cmd': '',
368          'postinstall_cmd': '/etc/init.d/pl_nm restart',
369          'error_cmd': '',
370          'ignore_cmd_errors': 1,
371          'always_update': 0},
372
373         # Proxy ARP setup
374         {'enabled': 1,
375          'source': 'PlanetLabConf/proxies.php',
376          'dest': '/etc/planetlab/proxies',
377          'file_permissions': '644',
378          'file_owner': 'root',
379          'file_group': 'root',
380          'preinstall_cmd': '',
381          'postinstall_cmd': '',
382          'error_cmd': '',
383          'ignore_cmd_errors': 0,
384          'always_update': 0},
385
386         # Firewall configuration
387         {'enabled': 1,
388          'source': 'PlanetLabConf/iptables',
389          'dest': '/etc/sysconfig/iptables',
390          'file_permissions': '600',
391          'file_owner': 'root',
392          'file_group': 'root',
393          'preinstall_cmd': '',
394          'postinstall_cmd': '',
395          'error_cmd': '',
396          'ignore_cmd_errors': 0,
397          'always_update': 0},
398         {'enabled': 1,
399          'source': 'PlanetLabConf/blacklist.php',
400          'dest': '/etc/planetlab/blacklist',
401          'file_permissions': '600',
402          'file_owner': 'root',
403          'file_group': 'root',
404          'preinstall_cmd': '',
405          'postinstall_cmd': '/sbin/iptables-restore --noflush < /etc/planetlab/blacklist',
406          'error_cmd': '',
407          'ignore_cmd_errors': 1,
408          'always_update': 1},
409
410         # /etc/issue
411         {'enabled': 1,
412          'source': 'PlanetLabConf/issue.php',
413          'dest': '/etc/issue',
414          'file_permissions': '644',
415          'file_owner': 'root',
416          'file_group': 'root',
417          'preinstall_cmd': '',
418          'postinstall_cmd': '',
419          'error_cmd': '',
420          'ignore_cmd_errors': 0,
421          'always_update': 0},
422
423         # Kernel parameters
424         {'enabled': 1,
425          'source': 'PlanetLabConf/sysctl.php',
426          'dest': '/etc/sysctl.conf',
427          'file_permissions': '644',
428          'file_owner': 'root',
429          'file_group': 'root',
430          'preinstall_cmd': '',
431          'postinstall_cmd': '/sbin/sysctl -e -p /etc/sysctl.conf',
432          'error_cmd': '',
433          'ignore_cmd_errors': 0,
434          'always_update': 1},
435
436         # Sendmail configuration
437         {'enabled': 1,
438          'source': 'PlanetLabConf/alpha-sendmail.mc',
439          'dest': '/etc/mail/sendmail.mc',
440          'file_permissions': '644',
441          'file_owner': 'root',
442          'file_group': 'root',
443          'preinstall_cmd': '',
444          'postinstall_cmd': '',
445          'error_cmd': '',
446          'ignore_cmd_errors': 0,
447          'always_update': 0},
448         {'enabled': 1,
449          'source': 'PlanetLabConf/alpha-sendmail.cf',
450          'dest': '/etc/mail/sendmail.cf',
451          'file_permissions': '644',
452          'file_owner': 'root',
453          'file_group': 'root',
454          'preinstall_cmd': '',
455          'postinstall_cmd': 'service sendmail restart',
456          'error_cmd': '',
457          'ignore_cmd_errors': 0,
458          'always_update': 0},
459
460         # GPG signing keys
461         {'enabled': 1,
462          'source': 'PlanetLabConf/RPM-GPG-KEY-fedora',
463          'dest': '/etc/pki/rpm-gpg/RPM-GPG-KEY-fedora',
464          'file_permissions': '644',
465          'file_owner': 'root',
466          'file_group': 'root',
467          'preinstall_cmd': '',
468          'postinstall_cmd': 'rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora',
469          'error_cmd': '',
470          'ignore_cmd_errors': 0,
471          'always_update': 0},
472         {'enabled': 1,
473          'source': 'PlanetLabConf/get_gpg_key.php',
474          'dest': '/etc/pki/rpm-gpg/RPM-GPG-KEY-planetlab',
475          'file_permissions': '644',
476          'file_owner': 'root',
477          'file_group': 'root',
478          'preinstall_cmd': '',
479          'postinstall_cmd': 'rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-planetlab',
480          'error_cmd': '',
481          'ignore_cmd_errors': 0,
482          'always_update': 0},
483
484         # Ping of death configuration
485         {'enabled': 1,
486          'source': 'PlanetLabConf/ipod.conf.php',
487          'dest': '/etc/ipod.conf',
488          'file_permissions': '644',
489          'file_owner': 'root',
490          'file_group': 'root',
491          'preinstall_cmd': '',
492          'postinstall_cmd': '',
493          'error_cmd': '',
494          'ignore_cmd_errors': 0,
495          'always_update': 0},
496
497         # sudo configuration
498         {'enabled': 1,
499          'source': 'PlanetLabConf/v3-sudoers.php',
500          'dest': '/etc/sudoers',
501          'file_permissions': '440',
502          'file_owner': 'root',
503          'file_group': 'root',
504          'preinstall_cmd': '',
505          'postinstall_cmd': '/usr/sbin/visudo -c',
506          'error_cmd': '',
507          'ignore_cmd_errors': 0,
508          'always_update': 0}]
509
510     # Get list of existing (enabled, global) files
511     conf_files = AdmGetConfFile()
512     conf_files = filter(lambda conf_file: conf_file['enabled'] and \
513                                           not conf_file['node_id'] and \
514                                           not conf_file['nodegroup_id'],
515                         conf_files)
516     dests = [conf_file['dest'] for conf_file in conf_files]
517     conf_files = dict(zip(dests, conf_files))
518
519     # Create/update default PlanetLabConf entries
520     for default_conf_file in default_conf_files:
521         if default_conf_file['dest'] not in dests:
522             AdmCreateConfFile(default_conf_file['enabled'],
523                               default_conf_file['source'],
524                               default_conf_file['dest'],
525                               default_conf_file['file_permissions'],
526                               default_conf_file['file_owner'],
527                               default_conf_file['file_group'],
528                               default_conf_file['preinstall_cmd'],
529                               default_conf_file['postinstall_cmd'],
530                               default_conf_file['error_cmd'],
531                               default_conf_file['ignore_cmd_errors'],
532                               default_conf_file['always_update'])
533         else:
534             conf_file = conf_files[default_conf_file['dest']]
535             AdmUpdateConfFile(conf_file['conf_file_id'], default_conf_file)
536
537     # Setup default slice attribute types
538     default_attribute_types = [
539         # Slice type (only vserver is supported)
540         {'name': "plc_slice_type",
541          'description': "Type of slice rspec to be created",
542          'is_exclusive': True, 'min_role_id': 20, 'max_per_slice': 1,
543          'value_fields': [{'description': "rspec class",
544                            'name': "type",
545                            'type': "string"}]},
546
547         # Slice initialization script
548         {'name': "initscript",
549          'description': "slice initialization script",
550          'is_exclusive': False, 'min_role_id': 10, 'max_per_slice': 1,
551          'value_fields': [{'description': "",
552                            'name': "initscript_id",
553                            'type': "integer"}]},
554
555         # CPU share (general_prop_share is deprecated)
556         {'name': "general_prop_share",
557          'description': "general share",
558          'is_exclusive': False, 'min_role_id': 10, 'max_per_slice': 1,
559          'value_fields': [{'description': "",
560                            'name': "general_prop_share",
561                            'type': "integer"}]},
562         {'name': "nm_cpu_share",
563          'description': "Number of CPU shares to be allocated to slice",
564          'is_exclusive': True, 'min_role_id': 10, 'max_per_slice': 1,
565          'value_fields': [{'description': "number of shares",
566                            'name': "cpu_share",
567                            'type': "integer"}]},
568
569         # Bandwidth limits
570         {'name': "nm_net_min_rate",
571          'description': "Minimum network Tx bandwidth",
572          'is_exclusive': True, 'min_role_id': 10, 'max_per_slice': 1,
573          'value_fields': [{'description': "rate (kbps)",
574                            'name': "rate",
575                            'type': "integer"}]},
576         {'name': "nm_net_max_rate",
577          'description': "Maximum network Tx bandwidth",
578          'is_exclusive': True, 'min_role_id': 10, 'max_per_slice': 1,
579          'value_fields': [{'description': "rate (kbps)",
580                            'name': "rate",
581                            'type': "integer"}]},
582         {'name': "nm_net_avg_rate",
583          'description': "Average daily network Tx bandwidth",
584          'is_exclusive': True, 'min_role_id': 10, 'max_per_slice': 1,
585          'value_fields': [{'description': "rate (kbps)",
586                            'name': "rate",
587                            'type': "integer"}]},
588         {'name': "nm_net_exempt_min_rate",
589          'description': "Minimum network Tx bandwidth to Internet2 destinations",
590          'is_exclusive': True, 'min_role_id': 10, 'max_per_slice': 1,
591          'value_fields': [{'description': "rate (kbps)",
592                            'name': "rate",
593                            'type': "integer"}]},
594         {'name': "nm_net_exempt_max_rate",
595          'description': "Maximum network Tx bandwidth to Internet2 destinations",
596          'is_exclusive': True, 'min_role_id': 10, 'max_per_slice': 1,
597          'value_fields': [{'description': "rate (kbps)",
598                            'name': "rate",
599                            'type': "integer"}]},
600         {'name': "nm_net_exempt avg_rate",
601          'description': "Average daily network Tx bandwidth to Internet2 destinations",
602          'is_exclusive': True, 'min_role_id': 10, 'max_per_slice': 1,
603          'value_fields': [{'description': "rate (kbps)",
604                            'name': "rate",
605                            'type': "integer"}]},
606
607         # Disk quota
608         {'name': "nm_disk_quota",
609          'description': "Disk quota",
610          'is_exclusive': True, 'min_role_id': 10, 'max_per_slice': 1,
611          'value_fields': [{'description': "Number of 1k disk blocks",
612                            'name': "quota",
613                            'type': "integer"}]},
614
615         # Special attributes applicable to Slice Creation Service (pl_conf) slice
616         {'name': "plc_agent_version",
617          'description': "Version of PLC agent (slice creation service) software to be deployed",
618          'is_exclusive': True, 'min_role_id': 10, 'max_per_slice': 1,
619          'value_fields': [{'description': "current version of PLC agent (SCS)",
620                            'name': "version",
621                            'type': "string"}]},
622         {'name': "plc_ticket_pubkey",
623          'description': "Public key used to verify PLC-signed tickets",
624          'is_exclusive': True, 'min_role_id': 10, 'max_per_slice': 1,
625          'value_fields': [{'description': "PEM-encoded public key",
626                            'name': "key",
627                            'type': "string"}]}]
628
629     # Get list of existing attribute types
630     attribute_types = SliceAttributeTypeList()
631
632     # Create/update default slice attribute types
633     for default_attribute_type in default_attribute_types:
634         if default_attribute_type['name'] not in attribute_types:
635             SliceAttributeTypeCreate(default_attribute_type['name'],
636                                      default_attribute_type['description'],
637                                      default_attribute_type['min_role_id'],
638                                      default_attribute_type['max_per_slice'],
639                                      default_attribute_type['is_exclusive'],
640                                      default_attribute_type['value_fields'])
641         else:
642             # XXX No way to update slice attribute types
643             pass
644
645     # Get contents of SSL public certificate used for signing tickets
646     try:
647         plc_ticket_pubkey = ""
648         for line in file(plc_api['ssl_key_pub']):
649             # Skip comments
650             if line[0:5] != "-----":
651                 # XXX The embedded newlines matter, do not strip()!
652                 plc_ticket_pubkey += line
653     except:
654         plc_ticket_pubkey = '%KEY%'
655
656     # Create/update system slices
657     slices = [{'name': "pl_conf",
658                'description': "PlanetLab Slice Creation Service (SCS)",
659                'url': url,
660                'attributes': {'plc_slice_type': {'type': "VServerSlice"},
661                               'plc_agent_version': {'version': "1.0"},
662                               'plc_ticket_pubkey': {'key': plc_ticket_pubkey}}},
663               {'name': "pl_conf_vserverslice",
664                'description': "Default attributes for vserver slices",
665                'url': url,
666                'attributes': {'nm_cpu_share': {'cpu_share': 32},
667                               'plc_slice_type': {'type': "VServerSlice"},
668                               'nm_disk_quota': {'quota': 5000000}}}]
669     for slice in slices:
670         try:
671             SliceInfo([slice['name']])
672         except:
673             SliceCreate(slice['name'])
674             SliceSetInstantiationMethod(slice['name'], 'plc-instantiated')
675         SliceUpdate(slice['name'], slice['url'], slice['description'])
676         # Renew forever
677         SliceRenew(slice['name'], sys.maxint)
678         # Create/update all attributes
679         for attribute, values in slice['attributes'].iteritems():
680             SliceAttributeSet(slice['name'], attribute, values)
681
682
683 if __name__ == '__main__':
684     main()