3 # Bootstraps the PLC database with a default administrator account and
6 # Mark Huang <mlhuang@cs.princeton.edu>
7 # Copyright (C) 2006 The Trustees of Princeton University
9 # $Id: api-config,v 1.4 2006/03/28 22:35:42 mlhuang Exp $
13 (plcapi, moreopts, argv) = plcapilib.plcapi(globals())
14 from plc_config import PLCConfiguration
20 cfg = PLCConfiguration()
22 variables = cfg.variables()
24 # Load variables into dictionaries
25 (category, variablelist) = variables['plc']
26 plc = dict(zip(variablelist.keys(),
27 [variable['value'] for variable in variablelist.values()]))
29 (category, variablelist) = variables['plc_www']
30 plc_www = dict(zip(variablelist.keys(),
31 [variable['value'] for variable in variablelist.values()]))
33 (category, variablelist) = variables['plc_api']
34 plc_api = dict(zip(variablelist.keys(),
35 [variable['value'] for variable in variablelist.values()]))
37 # Create/update the default administrator account (should be
39 admin = { 'person_id': 2,
40 'first_name': "Default",
41 'last_name': "Administrator",
42 'email': plc['root_user'],
43 'password': plc['root_password'] }
44 persons = AdmGetPersons([admin['person_id']])
46 person_id = AdmAddPerson(admin['first_name'], admin['last_name'], admin)
47 if person_id != admin['person_id']:
48 # Huh? Someone deleted the account manually from the database.
49 AdmDeletePerson(person_id)
50 raise Exception, "Someone deleted the \"%s %s\" account from the database!" % \
51 (admin['first_name'], admin['last_name'])
52 AdmSetPersonEnabled(person_id, True)
54 person_id = persons[0]['person_id']
55 AdmUpdatePerson(person_id, admin)
57 # Create/update the default site (should be site_id 0)
58 if plc_www['port'] == '80':
59 url = "http://" + plc_www['host'] + "/"
60 elif plc_www['port'] == '443':
61 url = "https://" + plc_www['host'] + "/"
63 url = "http://" + plc_www['host'] + ":" + plc_www['port'] + "/"
64 site = { 'site_id': 1,
65 'name': plc['name'] + " Central",
66 'abbreviated_name': plc['name'],
67 # XXX Default site slice_prefix/login_base must be "pl_"
68 # 'login_base': plc['slice_prefix'],
74 sites = AdmGetSites([site['site_id']])
76 site_id = AdmAddSite(site['name'], site['abbreviated_name'], site['login_base'], site)
77 if site_id != site['site_id']:
78 AdmDeleteSite(site_id)
79 raise Exception, "Someone deleted the \"%s\" site from the database!" % \
83 # Must call AdmUpdateSite() even after AdmAddSite() to update max_slices
84 site_id = sites[0]['site_id']
85 # XXX login_base cannot be updated
86 del site['login_base']
87 AdmUpdateSite(site_id, site)
89 # The default administrator account must be associated with a site
91 AdmAddPersonToSite(admin['person_id'], site['site_id'])
92 AdmSetPersonPrimarySite(admin['person_id'], site['site_id'])
94 # Grant admin and PI roles to the default administrator account
95 AdmGrantRoleToPerson(admin['person_id'], 10)
96 AdmGrantRoleToPerson(admin['person_id'], 20)
98 # Further bootstrap the database. A few PlanetLabConf entries are
99 # absolutely required, and NM requires the slice tables to be
102 # XXX This data should really become part of the DB schema so that
103 # we don't have to copy it from PLC. For now, this code is only
104 # intended to be called at build time, when we know that we have
105 # access to PLC. Once the tables have been populated, this code
106 # should never be called again and PLC access is not required,
107 # i.e., end users of MyPLC should never see this code be executed.
109 # Use xmlrpclib to connect to PLC temporarily. plcapilib cannot
110 # connect to multiple servers at once.
111 auth = {'AuthMethod': 'anonymous'}
114 conf_files = AdmGetConfFile()
117 PLC = xmlrpclib.Server("https://www.planet-lab.org/PLCAPI/")
118 for conf_file in PLC.AnonAdmGetConfFile(auth):
119 if conf_file['enabled'] and \
120 not conf_file['node_id'] and \
121 not conf_file['nodegroup_id']:
122 AdmCreateConfFile(conf_file['enabled'],
125 conf_file['file_permissions'],
126 conf_file['file_owner'],
127 conf_file['file_group'],
128 conf_file['preinstall_cmd'],
129 conf_file['postinstall_cmd'],
130 conf_file['error_cmd'],
131 conf_file['ignore_cmd_errors'],
132 conf_file['always_update'])
134 # Setup default slice attribute types, slices, and
135 # attributes. These are hard-coded here because we cannot safely
136 # support an anonymous interface to the SliceAttribute functions,
137 # yet we also do not want to require API authentication for
140 if not SliceAttributeTypeList():
141 # Create system attribute types
142 attribute_types = [{'name': "general_prop_share",
143 'description': "general share",
144 'is_exclusive': False, 'min_role_id': 10, 'max_per_slice': 1,
145 'value_fields': [{'description': "",
146 'name': "general_prop_share",
147 'type': "integer"}]},
148 {'name': "initscript",
149 'description': "slice initialization script",
150 'is_exclusive': False, 'min_role_id': 10, 'max_per_slice': 1,
151 'value_fields': [{'description': "",
152 'name': "initscript_id",
153 'type': "integer"}]},
154 {'name': "plc_slice_type",
155 'description': "Type of slice rspec to be created",
156 'is_exclusive': True, 'min_role_id': 20, 'max_per_slice': 1,
157 'value_fields': [{'description': "rspec class",
160 {'name': "nm_cpu_share",
161 'description': "Number of CPU shares to be allocated to slice",
162 'is_exclusive': True, 'min_role_id': 10, 'max_per_slice': 1,
163 'value_fields': [{'description': "number of shares",
165 'type': "integer"}]},
166 {'name': "plc_agent_version",
167 'description': "Version of PLC agent (slice creation service) software to be deployed",
168 'is_exclusive': True, 'min_role_id': 10, 'max_per_slice': 1,
169 'value_fields': [{'description': "current version of PLC agent (SCS)",
172 {'name': "plc_ticket_pubkey",
173 'description': "Public key used to verify PLC-signed tickets",
174 'is_exclusive': True, 'min_role_id': 10, 'max_per_slice': 1,
175 'value_fields': [{'description': "PEM-encoded public key",
178 {'name': "nm_disk_quota",
179 'description': "Disk quota",
180 'is_exclusive': True, 'min_role_id': 10, 'max_per_slice': 1,
181 'value_fields': [{'description': "Number of 1k disk blocks",
183 'type': "integer"}]}]
184 for attribute_type in attribute_types:
185 SliceAttributeTypeCreate(attribute_type['name'], attribute_type['description'],
186 attribute_type['min_role_id'], attribute_type['max_per_slice'],
187 attribute_type['is_exclusive'], attribute_type['value_fields'])
189 # Get contents of SSL public certificate used for signing tickets
191 plc_ticket_pubkey = ""
192 for line in file(plc_api['ssl_key_pub']):
194 if line[0:5] != "-----":
195 # XXX The embedded newlines matter, do not strip()!
196 plc_ticket_pubkey += line
198 plc_ticket_pubkey = '%KEY%'
200 # Create/update system slices
201 slices = [{'name': "pl_conf",
202 'description': "PlanetLab Slice Creation Service (SCS)",
204 'attributes': {'plc_slice_type': {'type': "VServerSlice"},
205 'plc_agent_version': {'version': "1.0"},
206 'plc_ticket_pubkey': {'key': plc_ticket_pubkey}}},
207 {'name': "pl_conf_vserverslice",
208 'description': "Default attributes for vserver slices",
210 'attributes': {'nm_cpu_share': {'cpu_share': 32},
211 'plc_slice_type': {'type': "VServerSlice"},
212 'nm_disk_quota': {'quota': 5000000}}}]
215 SliceInfo([slice['name']])
217 SliceCreate(slice['name'])
218 SliceSetInstantiationMethod(slice['name'], 'plc-instantiated')
219 SliceUpdate(slice['name'], slice['url'], slice['description'])
221 SliceRenew(slice['name'], sys.maxint)
222 # Create/update all attributes
223 for attribute, values in slice['attributes'].iteritems():
224 SliceAttributeSet(slice['name'], attribute, values)
227 if __name__ == '__main__':