3 # PlanetLab SFA implementation
5 # This implements the SFA Registry and Slice Interfaces on PLC.
6 # Depending on command line options, it starts some combination of a
7 # Registry, an Aggregate Manager, and a Slice Manager.
9 # There are several items that need to be done before starting the servers.
11 # NOTE: Many configuration settings, including the PLC maintenance account
12 # credentials, URI of the PLCAPI, and PLC DB URI and admin credentials are initialized
13 # from your MyPLC configuration (/etc/planetlab/plc_config*). Please make sure this information
14 # is up to date and accurate.
16 # 1) Import the existing planetlab database, creating the
17 # appropriate SFA records. This is done by running the "sfa-import.py" tool.
19 # 2) Create a "trusted_roots" directory and place the certificate of the root
20 # authority in that directory. Given the defaults in sfa-import-plc.py, this
21 # certificate would be named "planetlab.gid". For example,
23 # mkdir trusted_roots; cp authorities/planetlab.gid trusted_roots/
25 # TODO: Can all three servers use the same "registry" certificate?
28 # xxx todo not in the config yet
29 component_port = 12346
34 from optparse import OptionParser
36 from sfa.util.sfalogging import init_logger, logger
37 from sfa.util.xrn import get_authority, hrn_to_urn
38 from sfa.util.config import Config
40 from sfa.trust.gid import GID
41 from sfa.trust.trustedroots import TrustedRoots
42 from sfa.trust.certificate import Keypair, Certificate
43 from sfa.trust.hierarchy import Hierarchy
44 from sfa.trust.gid import GID
46 from sfa.server.sfaapi import SfaApi
47 from sfa.server.registry import Registries
48 from sfa.server.aggregate import Aggregates
50 from sfa.client.return_value import ReturnValue
55 Daemonize the current process.
56 after http://www.erlenstar.demon.co.uk/unix/faq_2.html
64 devnull = os.open(os.devnull, os.O_RDWR)
66 # xxx fixme - this is just to make sure that nothing gets stupidly lost -
68 logdir = '/var/log/httpd'
69 # when installed in standalone we might not have httpd installed
70 if not os.path.isdir(logdir):
71 os.mkdir('/var/log/httpd')
72 crashlog = os.open('%s/sfa_access_log' % logdir,
73 os.O_RDWR | os.O_APPEND | os.O_CREAT, 0644)
78 def install_peer_certs(server_key_file, server_cert_file):
80 Attempt to install missing trusted gids and db records for
81 our federated interfaces
83 # Attempt to get any missing peer gids
84 # There should be a gid file in /etc/sfa/trusted_roots for every
85 # peer registry found in in the registries.xml config file. If there
86 # are any missing gids, request a new one from the peer registry.
87 api = SfaApi(key_file=server_key_file, cert_file=server_cert_file)
88 registries = Registries()
89 aggregates = Aggregates()
90 interfaces = dict(registries.items() + aggregates.items())
91 gids_current = api.auth.trusted_cert_list
92 hrns_current = [gid.get_hrn() for gid in gids_current]
93 hrns_expected = set([hrn for hrn in interfaces])
94 new_hrns = set(hrns_expected).difference(hrns_current)
95 #gids = self.get_peer_gids(new_hrns) + gids_current
100 trusted_certs_dir = api.config.get_trustedroots_dir()
101 for new_hrn in new_hrns:
104 # the gid for this interface should already be installed
105 if new_hrn == api.config.SFA_INTERFACE_HRN:
108 # get gid from the registry
109 url = interfaces[new_hrn].get_url()
110 interface = interfaces[new_hrn].server_proxy(
111 server_key_file, server_cert_file, timeout=30)
112 # skip non sfa aggregates
113 server_version = api.get_cached_server_version(interface)
114 if 'sfa' not in server_version:
116 "get_trusted_certs: skipping non sfa aggregate: %s" % new_hrn)
119 trusted_gids = ReturnValue.get_value(interface.get_trusted_certs())
121 # the gid we want should be the first one in the list,
123 for trusted_gid in trusted_gids:
125 message = "interface: %s\t" % (api.interface)
126 message += "unable to install trusted gid for %s" % \
128 gid = GID(string=trusted_gid)
129 peer_gids.append(gid)
130 if gid.get_hrn() == new_hrn:
131 gid_filename = os.path.join(
132 trusted_certs_dir, '%s.gid' % new_hrn)
133 gid.save_to_file(gid_filename, save_parents=True)
134 message = "installed trusted cert for %s" % new_hrn
138 message = "interface: %s\tunable to install trusted gid for %s" % \
139 (api.interface, new_hrn)
140 logger.log_exc(message)
141 # doesnt matter witch one
142 update_cert_records(peer_gids)
145 def update_cert_records(gids):
147 Make sure there is a record in the registry for the specified gids.
148 Removes old records from the db.
150 # import db stuff here here so this module can be loaded by PlcComponentApi
151 from sfa.storage.alchemy import global_dbsession
152 from sfa.storage.model import RegRecord
153 dbsession = global_dbsession
156 # get records that actually exist in the db
157 gid_urns = [gid.get_urn() for gid in gids]
158 hrns_expected = [gid.get_hrn() for gid in gids]
159 records_found = dbsession.query(RegRecord).\
160 filter_by(pointer=-1).filter(RegRecord.hrn.in_(hrns_expected)).all()
163 for record in records_found:
164 if record.hrn not in hrns_expected and \
165 record.hrn != self.api.config.SFA_INTERFACE_HRN:
166 dbsession.delete(record)
168 # TODO: store urn in the db so we do this in 1 query
170 hrn, type = gid.get_hrn(), gid.get_type()
171 record = dbsession.query(RegRecord).filter_by(
172 hrn=hrn, type=type, pointer=-1).first()
177 'authority': get_authority(hrn),
178 'gid': gid.save_to_string(save_parents=True),
180 dbsession.add(record)
185 # Generate command line parser
186 parser = OptionParser(usage="sfa-start.py [options]")
187 parser.add_option("-r", "--registry", dest="registry", action="store_true",
188 help="run registry server", default=False)
189 parser.add_option("-s", "--slicemgr", dest="sm", action="store_true",
190 help="run slice manager", default=False)
191 parser.add_option("-a", "--aggregate", dest="am", action="store_true",
192 help="run aggregate manager", default=False)
193 parser.add_option("-c", "--component", dest="cm", action="store_true",
194 help="run component server", default=False)
195 parser.add_option("-t", "--trusted-certs",
196 dest="trusted_certs", action="store_true",
197 help="refresh trusted certs", default=False)
198 parser.add_option("-d", "--daemon", dest="daemon", action="store_true",
199 help="Run as daemon.", default=False)
200 (options, args) = parser.parse_args()
203 init_logger('server')
204 logger.setLevelFromOptVerbose(config.SFA_API_LOGLEVEL)
206 # ge the server's key and cert
207 hierarchy = Hierarchy()
208 auth_info = hierarchy.get_interface_auth_info()
209 server_key_file = auth_info.get_privkey_filename()
210 server_cert_file = auth_info.get_gid_filename()
212 # ensure interface cert is present in trusted roots dir
213 trusted_roots = TrustedRoots(config.get_trustedroots_dir())
214 trusted_roots.add_gid(GID(filename=server_cert_file))
218 if options.trusted_certs:
219 install_peer_certs(server_key_file, server_cert_file)
221 # start registry server
222 if (options.registry):
223 from sfa.server.registry import Registry
224 r = Registry("", config.SFA_REGISTRY_PORT,
225 server_key_file, server_cert_file)
229 from sfa.server.aggregate import Aggregate
230 a = Aggregate("", config.SFA_AGGREGATE_PORT,
231 server_key_file, server_cert_file)
234 # start slice manager
236 from sfa.server.slicemgr import SliceMgr
237 s = SliceMgr("", config.SFA_SM_PORT, server_key_file, server_cert_file)
241 from sfa.server.component import Component
242 c = Component("", config.component_port,
243 server_key_file, server_cert_file)
244 # c = Component("", config.SFA_COMPONENT_PORT, server_key_file, server_cert_file)
247 if __name__ == "__main__":
251 logger.log_exc("SFA server is exiting")