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 logger
37 from sfa.util.xrn import get_authority, hrn_to_urn
38 from sfa.util.config import Config
39 from sfa.trust.gid import GID
40 from sfa.trust.trustedroots import TrustedRoots
41 from sfa.trust.certificate import Keypair, Certificate
42 from sfa.trust.hierarchy import Hierarchy
43 from sfa.trust.gid import GID
44 from sfa.server.sfaapi import SfaApi
45 from sfa.server.registry import Registries
46 from sfa.server.aggregate import Aggregates
47 from sfa.client.return_value import ReturnValue
52 Daemonize the current process.
53 after http://www.erlenstar.demon.co.uk/unix/faq_2.html
61 devnull = os.open(os.devnull, os.O_RDWR)
63 # xxx fixme - this is just to make sure that nothing gets stupidly lost -
65 logdir = '/var/log/httpd'
66 # when installed in standalone we might not have httpd installed
67 if not os.path.isdir(logdir):
68 os.mkdir('/var/log/httpd')
69 crashlog = os.open('%s/sfa_access_log' % logdir, os.O_RDWR | os.O_APPEND | os.O_CREAT, 0644)
74 def install_peer_certs(server_key_file, server_cert_file):
76 Attempt to install missing trusted gids and db records for
77 our federated interfaces
79 # Attempt to get any missing peer gids
80 # There should be a gid file in /etc/sfa/trusted_roots for every
81 # peer registry found in in the registries.xml config file. If there
82 # are any missing gids, request a new one from the peer registry.
83 api = SfaApi(key_file=server_key_file, cert_file=server_cert_file)
84 registries = Registries()
85 aggregates = Aggregates()
86 interfaces = dict(registries.items() + aggregates.items())
87 gids_current = api.auth.trusted_cert_list
88 hrns_current = [gid.get_hrn() for gid in gids_current]
89 hrns_expected = set([hrn for hrn in interfaces])
90 new_hrns = set(hrns_expected).difference(hrns_current)
91 #gids = self.get_peer_gids(new_hrns) + gids_current
96 trusted_certs_dir = api.config.get_trustedroots_dir()
97 for new_hrn in new_hrns:
100 # the gid for this interface should already be installed
101 if new_hrn == api.config.SFA_INTERFACE_HRN:
104 # get gid from the registry
105 url = interfaces[new_hrn].get_url()
106 interface = interfaces[new_hrn].server_proxy(
107 server_key_file, server_cert_file, timeout=30)
108 # skip non sfa aggregates
109 server_version = api.get_cached_server_version(interface)
110 if 'sfa' not in server_version:
112 "get_trusted_certs: skipping non sfa aggregate: %s" % new_hrn)
115 trusted_gids = ReturnValue.get_value(interface.get_trusted_certs())
117 # the gid we want should be the first one in the list,
119 for trusted_gid in trusted_gids:
121 message = "interface: %s\t" % (api.interface)
122 message += "unable to install trusted gid for %s" % \
124 gid = GID(string=trusted_gid)
125 peer_gids.append(gid)
126 if gid.get_hrn() == new_hrn:
127 gid_filename = os.path.join(
128 trusted_certs_dir, '%s.gid' % new_hrn)
129 gid.save_to_file(gid_filename, save_parents=True)
130 message = "installed trusted cert for %s" % new_hrn
132 api.logger.info(message)
134 message = "interface: %s\tunable to install trusted gid for %s" % \
135 (api.interface, new_hrn)
136 api.logger.log_exc(message)
137 # doesnt matter witch one
138 update_cert_records(peer_gids)
141 def update_cert_records(gids):
143 Make sure there is a record in the registry for the specified gids.
144 Removes old records from the db.
146 # import db stuff here here so this module can be loaded by PlcComponentApi
147 from sfa.storage.alchemy import global_dbsession
148 from sfa.storage.model import RegRecord
149 dbsession = global_dbsession
152 # get records that actually exist in the db
153 gid_urns = [gid.get_urn() for gid in gids]
154 hrns_expected = [gid.get_hrn() for gid in gids]
155 records_found = dbsession.query(RegRecord).\
156 filter_by(pointer=-1).filter(RegRecord.hrn.in_(hrns_expected)).all()
159 for record in records_found:
160 if record.hrn not in hrns_expected and \
161 record.hrn != self.api.config.SFA_INTERFACE_HRN:
162 dbsession.delete(record)
164 # TODO: store urn in the db so we do this in 1 query
166 hrn, type = gid.get_hrn(), gid.get_type()
167 record = dbsession.query(RegRecord).filter_by(
168 hrn=hrn, type=type, pointer=-1).first()
170 record = RegRecord(dict={'type': type,
172 'authority': get_authority(hrn),
173 'gid': gid.save_to_string(save_parents=True),
175 dbsession.add(record)
180 # Generate command line parser
181 parser = OptionParser(usage="sfa-start.py [options]")
182 parser.add_option("-r", "--registry", dest="registry", action="store_true",
183 help="run registry server", default=False)
184 parser.add_option("-s", "--slicemgr", dest="sm", action="store_true",
185 help="run slice manager", default=False)
186 parser.add_option("-a", "--aggregate", dest="am", action="store_true",
187 help="run aggregate manager", default=False)
188 parser.add_option("-c", "--component", dest="cm", action="store_true",
189 help="run component server", default=False)
190 parser.add_option("-t", "--trusted-certs", dest="trusted_certs", action="store_true",
191 help="refresh trusted certs", default=False)
192 parser.add_option("-d", "--daemon", dest="daemon", action="store_true",
193 help="Run as daemon.", default=False)
194 (options, args) = parser.parse_args()
197 logger.setLevelFromOptVerbose(config.SFA_API_LOGLEVEL)
199 # ge the server's key and cert
200 hierarchy = Hierarchy()
201 auth_info = hierarchy.get_interface_auth_info()
202 server_key_file = auth_info.get_privkey_filename()
203 server_cert_file = auth_info.get_gid_filename()
205 # ensure interface cert is present in trusted roots dir
206 trusted_roots = TrustedRoots(config.get_trustedroots_dir())
207 trusted_roots.add_gid(GID(filename=server_cert_file))
211 if options.trusted_certs:
212 install_peer_certs(server_key_file, server_cert_file)
214 # start registry server
215 if (options.registry):
216 from sfa.server.registry import Registry
217 r = Registry("", config.SFA_REGISTRY_PORT,
218 server_key_file, server_cert_file)
222 from sfa.server.aggregate import Aggregate
223 a = Aggregate("", config.SFA_AGGREGATE_PORT,
224 server_key_file, server_cert_file)
227 # start slice manager
229 from sfa.server.slicemgr import SliceMgr
230 s = SliceMgr("", config.SFA_SM_PORT, server_key_file, server_cert_file)
234 from sfa.server.component import Component
235 c = Component("", config.component_port,
236 server_key_file, server_cert_file)
237 # c = Component("", config.SFA_COMPONENT_PORT, server_key_file, server_cert_file)
240 if __name__ == "__main__":
244 logger.log_exc_critical("SFA server is exiting")