Changeset e02cd14
- Timestamp:
- Feb 12, 2010 11:30:56 AM (15 years ago)
- Branches:
- axis_example, compt_changes, info-ops, master, version-3.01, version-3.02
- Children:
- eeb0088
- Parents:
- 8139a48
- Location:
- fedd/federation
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
fedd/federation/emulab_access.py
r8139a48 re02cd14 100 100 set_log_level(config, "access", self.log) 101 101 self.state_lock = Lock() 102 # XXX: Configurable 103 self.exports = set(('SMB', 'seer', 'tmcd')) 104 self.imports = set(('SMB', 'seer', 'tmcd')) 102 105 103 106 if auth: self.auth = auth … … 485 488 owners 486 489 487 def build_response(self, alloc_id, ap): 490 def export_services(self, sreq, project, user): 491 exp = [ ] 492 # XXX: Filthy shortcut here using http so urlparse will give the right 493 # answers. 494 for s in sreq: 495 sname = s.get('name', '') 496 svis = s.get('visibility', '') 497 if svis == 'export': 498 if sname in self.exports: 499 outs = s.copy() 500 if sname == 'SMB': 501 outs = s.copy() 502 outs['server'] = "http://fs:139" 503 outs['fedAttr'] = [ 504 { 'attribute': 'SMBSHARE', 'value': 'USERS' }, 505 { 'attribute': 'SMBUSER', 'value': user }, 506 { 'attribute': 'SMBPROJ', 'value': project }, 507 ] 508 elif sname == 'seer': 509 outs['server'] = "http://control:16606" 510 elif sname == 'tmcd': 511 outs['server'] = "http://boss:7777" 512 exp.append(outs) 513 return exp 514 515 def build_response(self, alloc_id, ap, services): 488 516 """ 489 517 Create the SOAP response. … … 508 536 [ { 'attribute': x, 'value' : y } \ 509 537 for x,y in self.attrs.iteritems()]) 538 539 if services: 540 msg['service'] = services 510 541 return msg 511 542 … … 676 707 "Misformed allocation response?") 677 708 678 679 709 self.allocation[aid]['owners'] = owners 680 710 self.write_state() … … 689 719 raise service_error(service_error.internal, 690 720 "Can't open %s/%s : %s" % (self.certdir, aid, e)) 691 resp = self.build_response({ 'fedid': allocID } , ap) 721 services = self.export_services(req.get('service',[]), pname, uname) 722 resp = self.build_response({ 'fedid': allocID } , ap, services) 692 723 return resp 693 724 else: … … 819 850 820 851 def generate_portal_configs(self, topo, pubkey_base, secretkey_base, 821 tmpdir, master): 852 tmpdir, master, lproj, leid, connInfo, services): 853 854 def conninfo_to_dict(key, info): 855 """ 856 Make a cpoy of the connection information about key, and flatten it 857 into a single dict by parsing out any feddAttrs. 858 """ 859 860 rv = None 861 for i in info: 862 if i.get('portal', "") == key: 863 rv = i.copy() 864 break 865 else: 866 return rv 867 868 if 'fedAttr' in rv: 869 for a in rv['fedAttr']: 870 attr = a.get('attribute', "") 871 val = a.get('value', "") 872 if attr and attr not in rv: 873 rv[attr] = val 874 del rv['fedAttr'] 875 return rv 876 877 # XXX: un hardcode this 878 def client_null(f, s): pass 879 880 def client_smb(f, s): 881 smbshare = None 882 smbuser = None 883 smbproj = None 884 for a in s.get('fedAttr', []): 885 if a.get('attribute', '') == 'SMBSHARE': 886 smbshare = a.get('value', None) 887 elif a.get('attribute', '') == 'SMBUSER': 888 smbuser = a.get('value', None) 889 elif a.get('attribute', '') == 'SMBPROJ': 890 smbproj = a.get('value', None) 891 892 if all((smbshare, smbuser, smbproj)): 893 print >>f, "SMBshare: %s" % smbshare 894 print >>f, "ProjectUser: %s" % smbuser 895 print >>f, "ProjectName: %s" % smbproj 896 897 client_service_out = { 898 'SMB': client_smb, 899 'tmcd': client_null, 900 'seer': client_null, 901 'userconfig': client_null, 902 } 903 # XXX: end un hardcode this 904 822 905 823 906 seer_out = False … … 826 909 if isinstance(e, topdl.Computer) and e.get_attribute('portal')]: 827 910 myname = e.name[0] 828 peer = e.get_attribute('peer') 829 lexp = e.get_attribute('experiment') 830 lproj, leid = lexp.split('/', 1) 831 ldomain = e.get_attribute('domain') 832 mexp = e.get_attribute('masterexperiment') 911 type = e.get_attribute('portal_type') 912 913 info = conninfo_to_dict(myname, connInfo) 914 915 if not info: 916 raise service_error(service_error.req, 917 "No connectivity info for %s" % myname) 918 919 peer = info.get('peer', "") 920 ldomain = self.domain; 921 922 mexp = info.get('masterexperiment',"") 833 923 mproj, meid = mexp.split("/", 1) 834 mdomain = e.get_attribute('masterdomain') 835 muser = e.get_attribute('masteruser') or 'root' 836 smbshare = e.get_attribute('smbshare') or 'USERS' 837 scriptdir = e.get_attribute('scriptdir') 838 active = e.get_attribute('active') 839 type = e.get_attribute('portal_type') 840 segid = fedid(hexstr=e.get_attribute('peer_segment')) 841 for e in topo.elements: 842 if isinstance(e, topdl.Segment) and e.id.fedid == segid: 843 seg = e 844 break 845 else: 846 raise service_error(service_error.req, 847 "Can't find segment for portal %s" % myname) 848 849 is_ip = re.match('\d+\.\d+\.\d+\.\d+', peer) 850 851 rexp = seg.get_attribute('experiment') 852 rproj, reid = rexp.split("/", 1) 853 rdomain = seg.get_attribute('domain') 924 mdomain = info.get('masterdomain',"") 925 muser = info.get('masteruser','root') 926 smbshare = info.get('smbshare', 'USERS') 927 928 active = info.get('active', 'False') 929 930 854 931 cfn = "%s/%s.gw.conf" % (tmpdir, myname.lower()) 855 932 tunnelconfig = self.attrs.has_key('TunnelCfg') … … 857 934 f = open(cfn, "w") 858 935 if active == 'True': 859 print >>f, "active: %s" % active860 936 if type in ('control', 'both'): 861 print >>f, 'port: remote:139:fs:139' 862 print >>f, 'port: remote:7777:boss:7777' 863 print >>f, 'port: remote:16606:control:16606' 937 for s in [s for s in services \ 938 if s.get('name', "") in self.imports]: 939 p = urlparse(s.get('server', 'http://localhost')) 940 print >>f, 'port: remote:%s:%s:%s' % \ 941 (p.port, p.hostname, p.port) 864 942 865 943 if tunnelconfig: 866 944 print >>f, "tunnelip: %s" % tunnelconfig 867 print >>f, "seercontrol: control.%s.%s%s" % \ 868 (meid.lower(), mproj.lower(), mdomain) 869 if is_ip: 870 print >>f, "peer: %s" % peer 871 else: 872 print >>f, "peer: %s.%s.%s%s" % \ 873 (peer.lower(), reid.lower(), 874 rproj.lower(), rdomain) 945 # XXX: send this an fedattr 946 #print >>f, "seercontrol: control.%s.%s%s" % \ 947 #(meid.lower(), mproj.lower(), mdomain) 948 print >>f, "peer: %s" % peer.lower() 875 949 print >>f, "ssh_pubkey: /proj/%s/exp/%s/tmp/%s" % \ 876 950 (lproj, leid, pubkey_base) … … 903 977 (myname.lower(), leid.lower(), lproj.lower(), 904 978 ldomain.lower()) 905 print >>f, "SMBshare: %s" % smbshare 906 print >>f, "ProjectUser: %s" % muser 907 print >>f, "ProjectName: %s" % mproj 908 print >>f, "ExperimentID: %s/%s" % (mproj, meid) 979 for s in services: 980 if s.get('name',"") in self.imports: 981 client_service_out[s['name']](f, s) 982 # Does seer need this? 983 # print >>f, "ExperimentID: %s/%s" % (mproj, meid) 909 984 f.close() 910 985 except IOError, e: … … 1051 1126 raise service_error(server_error.req, "Badly formed request") 1052 1127 1128 connInfo = req.get('connection', []) 1129 services = req.get('service', []) 1053 1130 auth_attr = req['allocID']['fedid'] 1054 1131 aid = "%s" % auth_attr … … 1083 1160 os.mkdir(softdir) 1084 1161 for s in sw: 1085 print "%s %s %s" % ( s, certfile, softdir)1162 self.log.debug("Retrieving %s" % s) 1086 1163 get_url(s, certfile, softdir) 1087 1164 … … 1131 1208 1132 1209 self.generate_portal_configs(topo, pubkey_base, 1133 secretkey_base, tmpdir, master) 1210 secretkey_base, tmpdir, master, proj, ename, connInfo, 1211 services) 1134 1212 self.generate_ns2(topo, expfile, 1135 1213 "/proj/%s/software/%s/" % (proj, ename), master) … … 1140 1218 except service_error, e: 1141 1219 err = e 1220 except e: 1221 err = service_error(service_error.internal, str(e)) 1142 1222 1143 1223 # Walk up tmpdir, deleting as we go -
fedd/federation/experiment_control.py
r8139a48 re02cd14 726 726 727 727 def get_access(self, tb, nodes, tbparam, master, export_project, 728 access_user ):728 access_user, services): 729 729 """ 730 730 Get access to testbed through fedd and set the parameters for that tb … … 769 769 # the type 770 770 req['exportProject'] = export_project 771 req['service'] = [ 772 { 'name': 'userconfig', 'visibility': 'export'}, 773 { 'name': 'SMB', 'visibility': 'export'}, 774 { 'name': 'seer', 'visibility': 'export'}, 775 { 'name': 'tmcd', 'visibility': 'export'}, 776 ] 771 777 772 778 # node resources if any … … 820 826 "uri": uri, 821 827 } 828 if 'service' in r: 829 services.extend(r['service']) 822 830 823 831 # Add attributes to parameter space. We don't allow attributes to … … 890 898 self.response = None 891 899 892 def __call__(self, uri, aid, topo, master, attrs=None): 900 def __call__(self, uri, aid, topo, master, attrs=None, connInfo=None, 901 services=None): 893 902 req = { 894 903 'allocID': { 'fedid' : aid }, … … 898 907 'master': master, 899 908 } 909 910 if connInfo: 911 req['connection'] = connInfo 912 # Add services to request. The master exports, everyone else 913 # imports. 914 if services: 915 svcs = [ x.copy() for x in services] 916 for s in svcs: 917 if master: s['visibility'] = 'export' 918 else: s['visibility'] = 'import' 919 req['service'] = svcs 900 920 if attrs: 901 921 req['fedAttr'] = attrs … … 950 970 def allocate_resources(self, allocated, master, eid, expid, 951 971 tbparams, topo, tmpdir, alloc_log=None, log_collector=None, 952 attrs=None ):972 attrs=None, connInfo={}, services=[]): 953 973 def get_vlan(r): 954 974 if r.has_key('StartSegmentResponseBody'): … … 1001 1021 t = self.pooled_thread( 1002 1022 target=ss, 1003 args =(uri, aid, topo[tb], False, attrs), 1023 args =(uri, aid, topo[tb], False, attrs, connInfo[tb], 1024 services), 1004 1025 name=tb, pdata=thread_pool, trace_file=self.trace_file) 1005 1026 threads.append(t) … … 1054 1075 caller=self.call_StartSegment, 1055 1076 log_collector=log_collector), 1056 args=(uri, aid, topo[tb], False, attrs), name=tb, 1077 args=(uri, aid, topo[tb], False, attrs, connInfo[tb], 1078 services), 1079 name=tb, 1057 1080 pdata=thread_pool, trace_file=self.trace_file) 1058 1081 threads.append(t) … … 1090 1113 caller=self.call_StartSegment, 1091 1114 log_collector=log_collector), 1092 args =(uri, aid, topo[master], True, attrs), 1115 args =(uri, aid, topo[master], True, attrs, 1116 connInfo[master], services), 1093 1117 name=master, pdata=thread_pool, trace_file=self.trace_file) 1094 1118 threads.append(t) … … 1294 1318 1295 1319 def get_access_to_testbeds(self, testbeds, access_user, 1296 export_project, master, allocated, tbparams ):1320 export_project, master, allocated, tbparams, services): 1297 1321 """ 1298 1322 Request access to the various testbeds required for this instantiation … … 1303 1327 for tb in testbeds: 1304 1328 self.get_access(tb, None, tbparams, master, 1305 export_project, access_user )1329 export_project, access_user, services) 1306 1330 allocated[tb] = 1 1307 1331 1308 1332 def split_topology(self, top, topo, testbeds, eid, master, tbparams): 1309 1333 """ 1310 Create the sub-topologies that are needed for experimetn instantiation. 1311 Along the way attach startup commands to the computers in the 1312 subtopologies. 1334 Create the sub-topologies that are needed for experiment instantiation. 1313 1335 """ 1314 1336 for tb in testbeds: 1315 1337 topo[tb] = top.clone() 1316 1338 to_delete = [ ] 1339 # XXX: copy in for loop to simplify 1317 1340 for e in topo[tb].elements: 1318 1341 etb = e.get_attribute('testbed') … … 1332 1355 for e in [ e for e in topo[tb].elements \ 1333 1356 if isinstance(e,topdl.Computer)]: 1334 if tb == master:1335 cmd = 'sudo -H /usr/local/federation/bin/make_hosts /proj/%s/exp/%s/tmp/hosts >& /tmp/federate' % (tbparams[tb].get('project', 'project'), eid)1336 else:1337 cmd = "sudo -H /bin/sh /usr/local/federation/bin/federate.sh >& /tmp/federate"1338 scmd = e.get_attribute('startup')1339 if scmd:1340 cmd = "%s \\$USER '%s'" % (cmd, scmd)1341 1342 e.set_attribute('startup', cmd)1343 1357 if self.fedkit: self.add_kit(e, self.fedkit) 1344 1358 1345 1359 def new_portal_node(self, st, dt, tbparams, master, eid, myname, desthost, 1346 1360 portal_type, iface_desc=()): 1361 """ 1362 Return a new internet portal node and a dict with the connectionInfo to 1363 be attached. 1364 """ 1347 1365 sproject = tbparams[st].get('project', 'project') 1348 dproject = tbparams[dt].get('project', 'project') 1366 sdomain = tbparams[st].get('domain', ".example.com") 1367 mdomain = tbparams[master].get('domain', '.example.com') 1349 1368 mproject = tbparams[master].get('project', 'project') 1350 sdomain = tbparams[st].get('domain', ".example.com")1351 ddomain = tbparams[dt].get('domain', ".example.com")1352 mdomain = tbparams[master].get('domain', '.example.com')1353 1369 muser = tbparams[master].get('user', 'root') 1354 1370 smbshare = tbparams[master].get('smbshare', 'USERS') 1355 aid = tbparams[dt]['allocID']['fedid'] 1371 1356 1372 if st == master or dt == master: 1357 1373 active = ("%s" % (st == master)) 1358 1374 else: 1359 active = ("%s" % (st > dt))1375 active = ("%s" % (st > dt)) 1360 1376 1361 1377 ifaces = [ ] … … 1371 1387 ) 1372 1388 ifaces.append(inf) 1373 return topdl.Computer( 1389 info = { 1390 "type" : "ssh", 1391 "portal": myname, 1392 'peer': "%s.%s.%s%s" % (desthost.lower(), eid.lower(), 1393 sproject.lower(), sdomain.lower()), 1394 'fedAttr': [ 1395 { 'attribute': 'masterdomain', 'value': mdomain}, 1396 { 'attribute': 'masterexperiment', 'value': 1397 "%s/%s" % (mproject, eid)}, 1398 { 'attribute': 'active', 'value': "%s" % active}, 1399 # Move to SMB service description 1400 { 'attribute': 'masteruser', 'value': muser}, 1401 { 'attribute': 'smbshare', 'value': smbshare}, 1402 ], 1403 } 1404 return (topdl.Computer( 1374 1405 name=myname, 1375 1406 attribute=[ … … 1377 1408 for n, v in (\ 1378 1409 ('portal', 'true'), 1379 ('domain', sdomain),1380 ('masterdomain', mdomain),1381 ('masterexperiment', "%s/%s" % \1382 (mproject, eid)),1383 ('masteruser', muser),1384 ('smbshare', smbshare),1385 ('experiment', "%s/%s" % \1386 (sproject, eid)),1387 ('peer', "%s" % desthost),1388 ('peer_segment', "%s" % aid),1389 ('scriptdir',1390 "/usr/local/federation/bin"),1391 ('active', "%s" % active),1392 1410 ('portal_type', portal_type), 1393 1411 ) 1394 1412 ], 1395 1413 interface=ifaces, 1396 ) 1414 ), info) 1397 1415 1398 1416 def new_portal_substrate(self, st, dt, eid, tbparams): … … 1496 1514 1497 1515 def insert_internet_portals(self, sub, topo, tbs, tbparams, master, eid, 1498 segment_substrate, portals ):1516 segment_substrate, portals, connInfo): 1499 1517 # More than one testbed is on this substrate. Insert 1500 1518 # some portals into the subtopologies. st == source testbed, … … 1505 1523 if not portals.has_key(st): 1506 1524 portals[st] = { } 1525 if not connInfo.has_key(st): 1526 connInfo[st] = [ ] 1507 1527 for dt in [ t for t in tbs.keys() if t != st]: 1508 1528 sproject = tbparams[st].get('project', 'project') … … 1531 1551 if portals[st].has_key(dt): 1532 1552 # There's a portal set up to go to this destination. 1533 # See if there's room to multiple sthis connection on1553 # See if there's room to multiplex this connection on 1534 1554 # it. If so, add an interface to the portal; if not, 1535 1555 # set up to add a portal below. … … 1573 1593 (('ip4_address', tbs[dt]),)) 1574 1594 ) 1575 portal = self.new_portal_node(st, dt, tbparams,1595 portal, info = self.new_portal_node(st, dt, tbparams, 1576 1596 master, eid, myname, desthost, portal_type, 1577 1597 infs) … … 1583 1603 topo[st].elements.append(portal) 1584 1604 portals[st][dt].append(portal) 1585 1586 def add_control_portal(self, st, dt, master, eid, topo, tbparams): 1605 connInfo[st].append(info) 1606 1607 def add_control_portal(self, st, dt, master, eid, topo, tbparams, connInfo): 1587 1608 # Add to the master testbed 1588 1609 tsubstrate, segment_element = \ … … 1591 1612 desthost = "%stunnel" % st 1592 1613 1593 portal = self.new_portal_node(st, dt, tbparams, master,1614 portal, info = self.new_portal_node(st, dt, tbparams, master, 1594 1615 eid, myname, desthost, "control", 1595 1616 ((tsubstrate.name,(('portal','true'),)),)) … … 1602 1623 topo[st].elements.append(segment_element) 1603 1624 topo[st].elements.append(portal) 1625 if not connInfo.has_key(st): 1626 connInfo[st] = [ ] 1627 connInfo[st].append(info) 1604 1628 1605 1629 def new_dragon_portal(self, st, dt, master, eid, myip, dip, idx, … … 1623 1647 return portal 1624 1648 1625 def add_portals(self, top, topo, eid, master, tbparams, ip_allocator): 1649 def add_portals(self, top, topo, eid, master, tbparams, ip_allocator, 1650 connInfo): 1626 1651 """ 1627 1652 For each substrate in the main topology, find those that … … 1652 1677 else: 1653 1678 self.insert_internet_portals(s, topo, tbs, tbparams, master, 1654 eid, segment_substrate, portals )1679 eid, segment_substrate, portals, connInfo) 1655 1680 1656 1681 # Make sure that all the slaves have a control portal back to the … … 1738 1763 else: 1739 1764 self.add_control_portal(master, tb, master, eid, topo, 1740 tbparams )1765 tbparams, connInfo) 1741 1766 self.add_control_portal(tb, master, master, eid, topo, 1742 tbparams )1767 tbparams, connInfo) 1743 1768 1744 1769 # Connect the portal nodes into the topologies and clear out … … 2030 2055 allocated = { } # Testbeds we can access 2031 2056 topo ={ } # Sub topologies 2057 connInfo = { } # Connection information 2058 services = [ ] 2032 2059 self.get_access_to_testbeds(testbeds, access_user, 2033 export_project, master, allocated, tbparams )2060 export_project, master, allocated, tbparams, services) 2034 2061 self.split_topology(top, topo, testbeds, eid, master, tbparams) 2035 2062 … … 2066 2093 self.auth.set_attribute(asignee, "%s/%s" % (configpath, f)) 2067 2094 2068 self.add_portals(top, topo, eid, master, tbparams, ip_allocator) 2095 self.add_portals(top, topo, eid, master, tbparams, ip_allocator, 2096 connInfo) 2069 2097 # Now get access to the dynamic testbeds 2070 2098 for k, t in topo.items(): … … 2074 2102 if tb: 2075 2103 self.get_access(tb, None, user, tbparams, master, 2076 export_project, access_user )2104 export_project, access_user, services) 2077 2105 tbparams[k] = tbparams[tb] 2078 2106 del tbparams[tb] … … 2168 2196 t = Thread(target=self.allocate_resources, 2169 2197 args=(allocated, master, eid, expid, tbparams, 2170 topo, tmpdir, alloc_log, alloc_collector, attrs), 2198 topo, tmpdir, alloc_log, alloc_collector, attrs, connInfo, 2199 services), 2171 2200 name=eid) 2172 2201 t.start()
Note: See TracChangeset
for help on using the changeset viewer.