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-plc.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
33 from optparse import OptionParser
35 from sfa.util.sfalogging import logger
36 from sfa.util.xrn import get_authority, hrn_to_urn
37 from sfa.util.config import Config
38 from sfa.trust.gid import GID
39 from sfa.trust.trustedroots import TrustedRoots
40 from sfa.trust.certificate import Keypair, Certificate
41 from sfa.trust.hierarchy import Hierarchy
42 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
49 # after http://www.erlenstar.demon.co.uk/unix/faq_2.html
51 """Daemonize the current process."""
52 if os.fork() != 0: os._exit(0)
54 if os.fork() != 0: os._exit(0)
56 devnull = os.open(os.devnull, os.O_RDWR)
58 # xxx fixme - this is just to make sure that nothing gets stupidly lost - should use devnull
59 logdir='/var/log/httpd'
60 # when installed in standalone we might not have httpd installed
61 if not os.path.isdir(logdir): os.mkdir('/var/log/httpd')
62 crashlog = os.open('%s/sfa_access_log'%logdir, os.O_RDWR | os.O_APPEND | os.O_CREAT, 0644)
67 def install_peer_certs(server_key_file, server_cert_file):
69 Attempt to install missing trusted gids and db records for
70 our federated interfaces
72 # Attempt to get any missing peer gids
73 # There should be a gid file in /etc/sfa/trusted_roots for every
74 # peer registry found in in the registries.xml config file. If there
75 # are any missing gids, request a new one from the peer registry.
76 print>>sys.stderr, " \r\n \r\n \t=============================================== install_peer_certs server_key_file %s server_cert_file %s"%(server_key_file,server_cert_file)
77 api = SfaApi(key_file = server_key_file, cert_file = server_cert_file)
78 registries = Registries()
79 aggregates = Aggregates()
80 interfaces = dict(registries.items() + aggregates.items())
81 gids_current = api.auth.trusted_cert_list
82 hrns_current = [gid.get_hrn() for gid in gids_current]
83 hrns_expected = set([hrn for hrn in interfaces])
84 new_hrns = set(hrns_expected).difference(hrns_current)
85 #gids = self.get_peer_gids(new_hrns) + gids_current
89 print>>sys.stderr," \r\n \r\n \t=============================================== install_peer_certs interfaces %s api.config.SFA_INTERFACE_HRN %s new_hrns %s" %( interfaces,api.config.SFA_INTERFACE_HRN,new_hrns)
90 trusted_certs_dir = api.config.get_trustedroots_dir()
91 for new_hrn in new_hrns:
92 if not new_hrn: continue
93 # the gid for this interface should already be installed
94 if new_hrn == api.config.SFA_INTERFACE_HRN: continue
96 # get gid from the registry
97 url = interfaces[new_hrn].get_url()
98 interface = interfaces[new_hrn].server_proxy(server_key_file, server_cert_file, timeout=30)
99 # skip non sfa aggregates
100 print>>sys.stderr, " \r\n \r\n \t=============================================== install_peer_certs IIIinterface %s url %s" %(interface,url)
101 server_version = api.get_cached_server_version(interface)
102 print>>sys.stderr, " \r\n \r\n \t=============================================== install_peer_certs server_version %s \r\n \r\rn \t\t =============================================== server_version['sfa'] %s, " %(server_version, server_version['sfa'])
103 if 'sfa' not in server_version:
104 logger.info("get_trusted_certs: skipping non sfa aggregate: %s" % new_hrn)
106 trusted_gids = ReturnValue.get_value(interface.get_trusted_certs())
107 #trusted_gids = interface.get_trusted_certs()
108 print>>sys.stderr, " \r\n \r\n \t=============================================== install_peer_certs TRUSTED_GIDS %s " %(trusted_gids)
110 #and not isinstance(trusted_gids,list):
111 # the gid we want should be the first one in the list,
113 #trusted_gids = [trusted_gids]
114 print>>sys.stderr, " \r\n \r\n \t=============================================== install_peer_certs TRUSTED_GIDS %s " %(trusted_gids)
115 for trusted_gid in trusted_gids:
116 print>>sys.stderr, " \r\n \r\n \t=============================================== install_peer_certs trusted_gids%s " %(trusted_gid)
118 message = "interface: %s\t" % (api.interface)
119 message += "unable to install trusted gid for %s" % \
121 print>>sys.stderr, " \r\n \r\n \t=============================================== install_peer_certs message %s " %(message)
122 #gid = GID(string=trusted_gids[0])
123 gid = GID(string=trusted_gid)
124 print>>sys.stderr, " \r\n \r\n \t=============================================== install_peer_certs gid %s " %(gid)
125 peer_gids.append(gid)
126 if gid.get_hrn() == new_hrn:
127 gid_filename = os.path.join(trusted_certs_dir, '%s.gid' % new_hrn)
128 gid.save_to_file(gid_filename, save_parents=True)
129 message = "installed trusted cert for %s" % new_hrn
131 api.logger.info(message)
133 message = "interface: %s\tunable to install trusted gid for %s" % \
134 (api.interface, new_hrn)
135 api.logger.log_exc(message)
136 # doesnt matter witch one
137 update_cert_records(peer_gids)
139 def update_cert_records(gids):
141 Make sure there is a record in the registry for the specified gids.
142 Removes old records from the db.
144 # import SfaTable here so this module can be loaded by PlcComponentApi
145 from sfa.storage.table import SfaTable
146 from sfa.storage.record import SfaRecord
150 # get records that actually exist in the db
151 gid_urns = [gid.get_urn() for gid in gids]
152 hrns_expected = [gid.get_hrn() for gid in gids]
153 records_found = table.find({'hrn': hrns_expected, 'pointer': -1})
156 for record in records_found:
157 if record['hrn'] not in hrns_expected and \
158 record['hrn'] != self.api.config.SFA_INTERFACE_HRN:
161 # TODO: store urn in the db so we do this in 1 query
163 hrn, type = gid.get_hrn(), gid.get_type()
164 print>>sys.stderr, " \r\n \r\n update_cert_records hrn,%s type %s"%(hrn, type)
165 record = table.find({'hrn': hrn, 'type': type, 'pointer': -1})
168 'hrn': hrn, 'type': type, 'pointer': -1,
169 'authority': get_authority(hrn),
170 'gid': gid.save_to_string(save_parents=True),
172 record = SfaRecord(dict=record)
173 print>>sys.stderr, " \r\n \r\rn record %s "%(record)
177 # Generate command line parser
178 parser = OptionParser(usage="sfa-start.py [options]")
179 parser.add_option("-r", "--registry", dest="registry", action="store_true",
180 help="run registry server", default=False)
181 parser.add_option("-s", "--slicemgr", dest="sm", action="store_true",
182 help="run slice manager", default=False)
183 parser.add_option("-a", "--aggregate", dest="am", action="store_true",
184 help="run aggregate manager", default=False)
185 parser.add_option("-c", "--component", dest="cm", action="store_true",
186 help="run component server", default=False)
187 parser.add_option("-t", "--trusted-certs", dest="trusted_certs", action="store_true",
188 help="refresh trusted certs", default=False)
189 parser.add_option("-d", "--daemon", dest="daemon", action="store_true",
190 help="Run as daemon.", default=False)
191 (options, args) = parser.parse_args()
194 logger.setLevelFromOptVerbose(config.SFA_API_LOGLEVEL)
197 # ge the server's key and cert
198 hierarchy = Hierarchy()
199 auth_info = hierarchy.get_interface_auth_info()
200 server_key_file = auth_info.get_privkey_filename()
201 server_cert_file = auth_info.get_gid_filename()
202 print>>sys.stderr, " \r\n \t\t\t\t\t SFA-START MAIN auth_info %s server_key_file %s server_cert_file %s "%(auth_info, server_key_file,server_cert_file)
203 # ensure interface cert is present in trusted roots dir
204 trusted_roots = TrustedRoots(config.get_trustedroots_dir())
205 trusted_roots.add_gid(GID(filename=server_cert_file))
206 if (options.daemon): daemon()
208 if options.trusted_certs:
209 install_peer_certs(server_key_file, server_cert_file)
211 # start registry server
212 if (options.registry):
213 from sfa.server.registry import Registry
214 r = Registry("", config.SFA_REGISTRY_PORT, server_key_file, server_cert_file)
218 from sfa.server.aggregate import Aggregate
219 a = Aggregate("", config.SFA_AGGREGATE_PORT, server_key_file, server_cert_file)
222 # start slice manager
224 from sfa.server.slicemgr import SliceMgr
225 s = SliceMgr("", config.SFA_SM_PORT, server_key_file, server_cert_file)
229 from sfa.server.component import Component
230 c = Component("", config.component_port, server_key_file, server_cert_file)
231 # c = Component("", config.SFA_COMPONENT_PORT, server_key_file, server_cert_file)
234 if __name__ == "__main__":
238 logger.log_exc_critical("SFA server is exiting")