Changeset 69692a9
- Timestamp:
- Sep 21, 2009 6:48:12 PM (15 years ago)
- Branches:
- axis_example, compt_changes, info-ops, master, version-2.00, version-3.01, version-3.02
- Children:
- ae0f69a
- Parents:
- adcbdaf
- Location:
- fedd/federation
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
fedd/federation/dragon_access.py
radcbdaf r69692a9 504 504 if not ep: 505 505 raise service_error(service_error.req, 506 "Missing DRAGON endpoint fo e %s" % s.name)506 "Missing DRAGON endpoint for %s" % s.id) 507 507 v = s.get_attribute('vlans') 508 508 vlans = None … … 669 669 return gri, vlan_no 670 670 else: 671 raise service_error(service_error.federant, "Cannot make reservation") 671 raise service_error(service_error.federant, 672 "Cannot make reservation") 672 673 673 674 def stop_segment(self, repo, gri, log=None): -
fedd/federation/emulab_access.py
radcbdaf r69692a9 69 69 self.ssh_privkey_file = config.get("access","ssh_privkey_file") 70 70 self.create_debug = config.getboolean("access", "create_debug") 71 self.cleanup = not config.getboolean("access", "leave_tmpfiles") 71 72 self.access_type = config.get("access", "type") 72 73 … … 915 916 916 917 def generate_ns2(self, topo, expfn, softdir, master): 918 def dragon_commands(e): 919 s = "" 920 if isinstance(e, topdl.Computer): 921 for i in e.interface: 922 vlan = i.get_attribute('dragon_vlan') 923 if vlan: 924 type = i.get_attribute('dragon_type') 925 ip = i.get_attribute('ip4_address') 926 if type == 'link': 927 s = ("tb-allow-external $%s dragonportal " + \ 928 "ip %s vlan %s\n") % \ 929 (topdl.to_tcl_name(e.name[0]), ip, vlan) 930 elif type == 'lan': 931 s = ("tb-allow-external $%s dragonportal " + \ 932 "ip %s vlan %s usurp %s\n") % \ 933 (topdl.to_tcl_name(e.name[0]), ip, vlan, 934 i.substrate[0]) 935 else: 936 raise service_error(service_error_internal, 937 "Unknown DRAGON type %s" % type) 938 return s 939 940 def not_dragon(e): 941 return all([not i.get_attribute('dragon_vlan') \ 942 for i in e.interface]) 943 917 944 t = topo.clone() 918 945 … … 925 952 if isinstance(e, topdl.Computer): 926 953 e.interface = [i for i in e.interface \ 927 if not i.get_attribute('portal')] 928 t.substrates = [ s for s in t.substrates \ 929 if not s.get_attribute('portal')] 954 if not i.get_attribute('portal') or \ 955 i.get_attribute('dragon_vlan')] 956 t.substrates = [ s.clone() for s in t.substrates ] 957 #t.substrates = [ s for s in t.substrates \ 958 # if not s.get_attribute('portal')] 930 959 t.incorporate_elements() 931 960 … … 941 970 else:cmdname = 'SlaveConnectorCmd' 942 971 972 if self.attrs.has_key('dragon'): 973 add_filter = not_dragon 974 filters.append(dragon_commands) 975 else: 976 add_filter = None 977 943 978 if self.attrs.has_key(cmdname): 944 979 filters.append(topdl.generate_portal_command_filter( 945 self.attrs.get(cmdname) ))980 self.attrs.get(cmdname), add_filter=add_filter)) 946 981 947 982 if self.attrs.has_key('connectorImage'): … … 1086 1121 err = e 1087 1122 1088 self.log.debug("[StartSegment]: removing %s" % tmpdir)1089 1123 # Walk up tmpdir, deleting as we go 1090 for path, dirs, files in os.walk(tmpdir, topdown=False): 1091 for f in files: 1092 os.remove(os.path.join(path, f)) 1093 for d in dirs: 1094 os.rmdir(os.path.join(path, d)) 1095 os.rmdir(tmpdir) 1124 if self.cleanup: 1125 self.log.debug("[StartSegment]: removing %s" % tmpdir) 1126 for path, dirs, files in os.walk(tmpdir, topdown=False): 1127 for f in files: 1128 os.remove(os.path.join(path, f)) 1129 for d in dirs: 1130 os.rmdir(os.path.join(path, d)) 1131 os.rmdir(tmpdir) 1132 else: 1133 self.log.debug("[StartSegment]: not removing %s" % tmpdir) 1096 1134 1097 1135 if rv: -
fedd/federation/experiment_control.py
radcbdaf r69692a9 233 233 234 234 self.debug = config.getboolean("experiment_control", "create_debug") 235 self.cleanup = not config.getboolean("experiment_control", 236 "leave_tmpfiles") 235 237 self.state_filename = config.get("experiment_control", 236 238 "experiment_state") … … 816 818 "Access denied by %s (%s)" % (tb, uri)) 817 819 818 e = r['emulab'] 819 p = e['project'] 820 tbparam[tb] = { 821 "boss": e['boss'], 822 "host": e['ops'], 823 "domain": e['domain'], 824 "fs": e['fileServer'], 825 "eventserver": e['eventServer'], 826 "project": unpack_id(p['name']), 827 "emulab" : e, 828 "allocID" : r['allocID'], 829 } 830 # Make the testbed name be the label the user applied 831 p['testbed'] = {'localname': tb } 832 833 for u in p['user']: 834 role = u.get('role', None) 835 if role == 'experimentCreation': 836 tbparam[tb]['user'] = unpack_id(u['userID']) 837 break 838 else: 839 raise service_error(service_error.internal, 840 "No createExperimentUser from %s" %tb) 841 842 # Add attributes to barameter space. We don't allow attributes to 843 # overlay any parameters already installed. 844 for a in e['fedAttr']: 845 try: 846 if a['attribute'] and isinstance(a['attribute'], basestring)\ 847 and not tbparam[tb].has_key(a['attribute'].lower()): 848 tbparam[tb][a['attribute'].lower()] = a['value'] 849 except KeyError: 850 self.log.error("Bad attribute in response: %s" % a) 820 if r.has_key('emulab'): 821 e = r['emulab'] 822 p = e['project'] 823 tbparam[tb] = { 824 "boss": e['boss'], 825 "host": e['ops'], 826 "domain": e['domain'], 827 "fs": e['fileServer'], 828 "eventserver": e['eventServer'], 829 "project": unpack_id(p['name']), 830 "emulab" : e, 831 "allocID" : r['allocID'], 832 "uri": uri, 833 } 834 # Make the testbed name be the label the user applied 835 p['testbed'] = {'localname': tb } 836 837 for u in p['user']: 838 role = u.get('role', None) 839 if role == 'experimentCreation': 840 tbparam[tb]['user'] = unpack_id(u['userID']) 841 break 842 else: 843 raise service_error(service_error.internal, 844 "No createExperimentUser from %s" %tb) 845 # Add attributes to parameter space. We don't allow attributes to 846 # overlay any parameters already installed. 847 for a in e['fedAttr']: 848 try: 849 if a['attribute'] and \ 850 isinstance(a['attribute'], basestring)\ 851 and not tbparam[tb].has_key(a['attribute'].lower()): 852 tbparam[tb][a['attribute'].lower()] = a['value'] 853 except KeyError: 854 self.log.error("Bad attribute in response: %s" % a) 855 else: 856 tbparam[tb] = { 857 "allocID" : r['allocID'], 858 "uri": uri, 859 } 860 851 861 852 def release_access(self, tb, aid ):862 def release_access(self, tb, aid, uri=None): 853 863 """ 854 864 Release access to testbed through fedd 855 865 """ 856 866 857 uri = self.tbmap.get(tb, None) 867 if not uri: 868 uri = self.tbmap.get(tb, None) 858 869 if not uri: 859 raise service_error(ser ice_error.server_config,870 raise service_error(service_error.server_config, 860 871 "Unknown testbed: %s" % tb) 861 872 … … 905 916 self.testbed = testbed 906 917 self.log_collector = log_collector 918 self.response = None 907 919 908 920 def __call__(self, uri, aid, topo, master, attrs=None): … … 927 939 for line in lval.splitlines(True): 928 940 self.log_collector.write(line) 941 self.response = r 929 942 else: 930 943 raise service_error(service_error.internal, … … 966 979 tbparams, topo, tmpdir, alloc_log=None, log_collector=None, 967 980 attrs=None): 981 def get_vlan(r): 982 if r.has_key('StartSegmentResponseBody'): 983 srb = r['StartSegmentResponseBody'] 984 if srb.has_key('fedAttr'): 985 for k, v in [ (a['attribute'], a['value']) \ 986 for a in srb['fedAttr']]: 987 if k == 'vlan': return v 988 return None 989 968 990 started = { } # Testbeds where a sub-experiment started 969 991 # successfully … … 972 994 fail_soft = False 973 995 996 slaves = [ k for k in allocated.keys() \ 997 if k != master and not topo[k].get_attribute('transit')] 998 transit = [ k for k in allocated.keys() \ 999 if topo[k].get_attribute('transit')] 1000 974 1001 log = alloc_log or self.log 975 1002 … … 977 1004 threads = [ ] 978 1005 979 for tb in [ k for k in allocated.keys() if k != master]: 980 # Create and start a thread to start the segment, and save it to 981 # get the return value later 982 thread_pool.wait_for_slot() 983 uri = self.tbmap.get(tb, None) 984 if not uri: 985 raise service_error(service_error.internal, 986 "Unknown testbed %s !?" % tb) 987 1006 for tb in transit: 1007 uri = tbparams[tb]['uri'] 988 1008 if tbparams[tb].has_key('allocID') and \ 989 1009 tbparams[tb]['allocID'].has_key('fedid'): … … 993 1013 "No alloc id for testbed %s !?" % tb) 994 1014 995 t = self.pooled_thread(\ 996 target=self.start_segment(log=log, debug=self.debug, 997 testbed=tb, cert_file=self.cert_file, 998 cert_pwd=self.cert_pwd, 999 trusted_certs=self.trusted_certs, 1000 caller=self.call_StartSegment, 1001 log_collector=log_collector), 1002 args=(uri, aid, topo[tb], False, attrs), name=tb, 1003 pdata=thread_pool, trace_file=self.trace_file) 1004 threads.append(t) 1005 t.start() 1006 1007 # Wait until all finish (keep pinging the log, though) 1008 mins = 0 1009 while not thread_pool.wait_for_all_done(60.0): 1010 mins += 1 1011 alloc_log.info("Waiting for sub threads (it has been %d mins)" \ 1012 % mins) 1013 1014 thread_pool.clear() 1015 m = re.search('(\d+)', tb) 1016 if m: 1017 to_repl = "unassigned%s" % m.group(1) 1018 else: 1019 raise service_error(service_error.internal, 1020 "Bad dynamic allocation name") 1021 break 1022 1023 ss = self.start_segment(log=log, debug=self.debug, 1024 testbed=master, cert_file=self.cert_file, 1025 cert_pwd=self.cert_pwd, 1026 trusted_certs=self.trusted_certs, 1027 caller=self.call_StartSegment, 1028 log_collector=log_collector) 1029 t = self.pooled_thread( 1030 target=ss, 1031 args =(uri, aid, topo[tb], False, attrs), 1032 name=tb, pdata=thread_pool, trace_file=self.trace_file) 1033 threads.append(t) 1034 t.start() 1035 # Wait until the this transit node finishes (keep pinging the log, 1036 # though) 1037 1038 mins = 0 1039 while not thread_pool.wait_for_all_done(60.0): 1040 mins += 1 1041 alloc_log.info("Waiting for master (it has been %d mins)" \ 1042 % mins) 1043 1044 if t.rv: 1045 vlan = get_vlan(ss.response) 1046 if vlan is not None: 1047 for k, t in topo.items(): 1048 for e in t.elements: 1049 for i in e.interface: 1050 vl = i.get_attribute('dragon_vlan') 1051 if vl is not None and vl == to_repl: 1052 i.set_attribute('dragon_vlan', vlan) 1053 else: 1054 break 1055 thread_pool.clear() 1056 1057 1058 failed = [ t.getName() for t in threads if not t.rv ] 1059 1060 if len(failed) == 0: 1061 for tb in slaves: 1062 # Create and start a thread to start the segment, and save it 1063 # to get the return value later 1064 thread_pool.wait_for_slot() 1065 uri = self.tbmap.get(tb, None) 1066 if not uri: 1067 raise service_error(service_error.internal, 1068 "Unknown testbed %s !?" % tb) 1069 1070 if tbparams[tb].has_key('allocID') and \ 1071 tbparams[tb]['allocID'].has_key('fedid'): 1072 aid = tbparams[tb]['allocID']['fedid'] 1073 else: 1074 raise service_error(service_error.internal, 1075 "No alloc id for testbed %s !?" % tb) 1076 1077 t = self.pooled_thread(\ 1078 target=self.start_segment(log=log, debug=self.debug, 1079 testbed=tb, cert_file=self.cert_file, 1080 cert_pwd=self.cert_pwd, 1081 trusted_certs=self.trusted_certs, 1082 caller=self.call_StartSegment, 1083 log_collector=log_collector), 1084 args=(uri, aid, topo[tb], False, attrs), name=tb, 1085 pdata=thread_pool, trace_file=self.trace_file) 1086 threads.append(t) 1087 t.start() 1088 1089 # Wait until all finish (keep pinging the log, though) 1090 mins = 0 1091 while not thread_pool.wait_for_all_done(60.0): 1092 mins += 1 1093 alloc_log.info("Waiting for sub threads (it has been %d mins)" \ 1094 % mins) 1095 1096 thread_pool.clear() 1015 1097 1016 1098 # If none failed, start the master … … 1074 1156 # release the allocations 1075 1157 for tb in tbparams.keys(): 1076 self.release_access(tb, tbparams[tb]['allocID']) 1158 self.release_access(tb, tbparams[tb]['allocID'], 1159 tbparams[tb].get('uri', None)) 1077 1160 # Remove the placeholder 1078 1161 self.state_lock.acquire() … … 1086 1169 log.info("[start_segment]: Experiment %s active" % eid) 1087 1170 1088 log.debug("[start_experiment]: removing %s" % tmpdir)1089 1171 1090 1172 # Walk up tmpdir, deleting as we go 1091 for path, dirs, files in os.walk(tmpdir, topdown=False): 1092 for f in files: 1093 os.remove(os.path.join(path, f)) 1094 for d in dirs: 1095 os.rmdir(os.path.join(path, d)) 1096 os.rmdir(tmpdir) 1173 if self.cleanup: 1174 log.debug("[start_experiment]: removing %s" % tmpdir) 1175 for path, dirs, files in os.walk(tmpdir, topdown=False): 1176 for f in files: 1177 os.remove(os.path.join(path, f)) 1178 for d in dirs: 1179 os.rmdir(os.path.join(path, d)) 1180 os.rmdir(tmpdir) 1181 else: 1182 log.debug("[start_experiment]: not removing %s" % tmpdir) 1097 1183 1098 1184 # Insert the experiment into our state and update the disk copy … … 1190 1276 def allocate_ips_to_topo(self, top): 1191 1277 """ 1192 Add an ip4_address attribute to all the hosts in t ehtopology, based on1278 Add an ip4_address attribute to all the hosts in the topology, based on 1193 1279 the shared substrates on which they sit. An /etc/hosts file is also 1194 created and returned as a list of hostfiles entries. 1280 created and returned as a list of hostfiles entries. We also return 1281 the allocator, because we may need to allocate IPs to portals 1282 (specifically DRAGON portals). 1195 1283 """ 1196 1284 subs = sorted(top.substrates, … … 1230 1318 ifs[hname] += 1 1231 1319 base += 1 1232 return hosts 1320 return hosts, ips 1233 1321 1234 1322 def get_access_to_testbeds(self, testbeds, user, access_user, … … 1283 1371 1284 1372 def new_portal_node(self, st, dt, tbparams, master, eid, myname, desthost, 1285 portal_type, portal_subst, subst=None, addr=None):1373 portal_type, iface_desc=()): 1286 1374 sproject = tbparams[st].get('project', 'project') 1287 1375 dproject = tbparams[dt].get('project', 'project') … … 1298 1386 active = ("%s" %(st > dt)) 1299 1387 1300 ifaces = [ 1301 topdl.Interface( 1302 substrate=portal_subst, 1303 attribute=[ 1304 topdl.Attribute(attribute='portal', 1305 value='true') 1306 ] 1307 ), 1308 ] 1309 if subst and addr: 1310 ifaces.append( 1311 topdl.Interface( 1312 substrate=subst, 1313 attribute=[ 1314 topdl.Attribute( 1315 attribute='ip4_address', 1316 value=addr, 1317 ) 1388 ifaces = [ ] 1389 for sub, attrs in iface_desc: 1390 inf = topdl.Interface( 1391 substrate=sub, 1392 attribute=[ 1393 topdl.Attribute( 1394 attribute=n, 1395 value = v) 1396 for n, v in attrs 1318 1397 ] 1319 )) 1320 1321 1398 ) 1399 ifaces.append(inf) 1322 1400 return topdl.Computer( 1323 1401 name=myname, … … 1340 1418 ('active', "%s" % active), 1341 1419 ('portal_type', portal_type), 1342 ('startup', 'sudo -H /usr/local/federation/bin/fed-tun.pl -f /proj/%s/exp/%s/tmp/%s.%s.%s%s.gw.conf >& /tmp/bridge.log' % (sproject, eid, myname.lower(), eid.lower(), sproject.lower(), sdomain.lower())))1420 ('startup', 'sudo -H /usr/local/federation/bin/fed-tun.pl >& /tmp/bridge.log')) 1343 1421 ], 1344 1422 interface=ifaces, … … 1375 1453 return (tsubstrate, segment_element) 1376 1454 1377 def add_portals(self, top, topo, eid, master, tbparams): 1455 def new_dragon_topo(self, idx, sub, topo, tbs, tbparams): 1456 if sub.capacity is None: 1457 raise service_error(service_error.internal, 1458 "Cannot DRAGON split substrate w/o capacity") 1459 segs = [ ] 1460 substr = topdl.Substrate(name="dragon%d" % idx, 1461 capacity=sub.capacity.clone(), 1462 attribute=[ topdl.Attribute(attribute=n, value=v) 1463 for n, v, in (\ 1464 ('vlan', 'unassigned%d' % idx),)]) 1465 for tb in tbs.keys(): 1466 seg = topdl.Segment( 1467 id = tbparams[tb]['allocID'], 1468 type='emulab', 1469 uri = self.tbmap.get(tb, None), 1470 interface=[ 1471 topdl.Interface( 1472 substrate=substr.name), 1473 ], 1474 attribute=[ topdl.Attribute( 1475 attribute='dragon_endpoint', value='true'), 1476 ] 1477 ) 1478 if tbparams[tb].has_key('vlans'): 1479 seg.set_attribute('vlans', tbparams[tb]['vlans']) 1480 segs.append(seg) 1481 1482 topo["dragon%d" %idx] = \ 1483 topdl.Topology(substrates=[substr], elements=segs, 1484 attribute=[ 1485 topdl.Attribute(attribute="transit", value='true'), 1486 topdl.Attribute(attribute="dynamic", value='true'), 1487 topdl.Attribute(attribute="testbed", value='dragon'), 1488 ] 1489 ) 1490 1491 def create_dragon_substrate(self, sub, topo, tbs, tbparams, master, eid): 1492 """ 1493 Add attribiutes to the various elements indicating that they are to be 1494 dragon connected and create a dragon segment in tops to be 1495 instantiated. 1496 """ 1497 1498 def get_substrate_from_topo(name, t): 1499 for s in t.substrates: 1500 if s.name == name: return s 1501 else: return None 1502 1503 dn = len([x for x in topo.keys() if x.startswith('dragon')]) 1504 elements = [ i.element for i in sub.interfaces ] 1505 count = { } 1506 for e in elements: 1507 tb = e.get_attribute('testbed') 1508 count[tb] = count.get(tb, 0) + 1 1509 1510 for tb in tbs.keys(): 1511 s = get_substrate_from_topo(sub.name, topo[tb]) 1512 if s: 1513 for i in s.interfaces: 1514 i.set_attribute('dragon_vlan', 'unassigned%d' % dn) 1515 if count[tb] > 1: i.set_attribute('dragon_type', 'lan') 1516 else: i.set_attribute('dragon_type', 'link') 1517 else: 1518 raise service_error(service_error.internal, 1519 "No substrate %s in testbed %s" % (sub.name, tb)) 1520 1521 self.new_dragon_topo(dn, sub, topo, tbs, tbparams) 1522 1523 def insert_internet_portals(self, sub, topo, tbs, tbparams, master, eid, 1524 segment_substrate, portals): 1525 # More than one testbed is on this substrate. Insert 1526 # some portals into the subtopologies. st == source testbed, 1527 # dt == destination testbed. 1528 for st in tbs.keys(): 1529 if not segment_substrate.has_key(st): 1530 segment_substrate[st] = { } 1531 if not portals.has_key(st): 1532 portals[st] = { } 1533 for dt in [ t for t in tbs.keys() if t != st]: 1534 sproject = tbparams[st].get('project', 'project') 1535 dproject = tbparams[dt].get('project', 'project') 1536 mproject = tbparams[master].get('project', 'project') 1537 sdomain = tbparams[st].get('domain', ".example.com") 1538 ddomain = tbparams[dt].get('domain', ".example.com") 1539 mdomain = tbparams[master].get('domain', '.example.com') 1540 muser = tbparams[master].get('user', 'root') 1541 smbshare = tbparams[master].get('smbshare', 'USERS') 1542 aid = tbparams[dt]['allocID']['fedid'] 1543 if st == master or dt == master: 1544 active = ("%s" % (st == master)) 1545 else: 1546 active = ("%s" %(st > dt)) 1547 if not segment_substrate[st].has_key(dt): 1548 # Put a substrate and a segment for the connected 1549 # testbed in there. 1550 tsubstrate, segment_element = \ 1551 self.new_portal_substrate(st, dt, eid, tbparams) 1552 segment_substrate[st][dt] = tsubstrate 1553 topo[st].substrates.append(tsubstrate) 1554 topo[st].elements.append(segment_element) 1555 1556 new_portal = False 1557 if portals[st].has_key(dt): 1558 # There's a portal set up to go to this destination. 1559 # See if there's room to multiples this connection on 1560 # it. If so, add an interface to the portal; if not, 1561 # set up to add a portal below. 1562 # [This little festival of braces is just a pop of the 1563 # last element in the list of portals between st and 1564 # dt.] 1565 portal = portals[st][dt][-1] 1566 mux = len([ i for i in portal.interface \ 1567 if not i.get_attribute('portal')]) 1568 if mux == self.muxmax: 1569 new_portal = True 1570 portal_type = "experiment" 1571 myname = "%stunnel%d" % (dt, len(portals[st][dt])) 1572 desthost = "%stunnel%d" % (st, len(portals[st][dt])) 1573 else: 1574 new_i = topdl.Interface( 1575 substrate=s.name, 1576 attribute=[ 1577 topdl.Attribute( 1578 attribute='ip4_address', 1579 value=tbs[dt] 1580 ) 1581 ]) 1582 portal.interface.append(new_i) 1583 else: 1584 # First connection to this testbed, make an empty list 1585 # and set up to add the new portal below 1586 new_portal = True 1587 portals[st][dt] = [ ] 1588 myname = "%stunnel%d" % (dt, len(portals[st][dt])) 1589 desthost = "%stunnel%d" % (st, len(portals[st][dt])) 1590 1591 if dt == master or st == master: portal_type = "both" 1592 else: portal_type = "experiment" 1593 1594 if new_portal: 1595 infs = ( 1596 (segment_substrate[st][dt].name, 1597 (('portal', 'true'),)), 1598 (sub.name, 1599 (('ip4_address', tbs[dt]),)) 1600 ) 1601 portal = self.new_portal_node(st, dt, tbparams, 1602 master, eid, myname, desthost, portal_type, 1603 infs) 1604 if self.fedkit: 1605 self.add_kit(portal, self.fedkit) 1606 if self.gatewaykit: 1607 self.add_kit(portal, self.gatewaykit) 1608 1609 topo[st].elements.append(portal) 1610 portals[st][dt].append(portal) 1611 1612 def add_control_portal(self, st, dt, master, eid, topo, tbparams): 1613 # Add to the master testbed 1614 tsubstrate, segment_element = \ 1615 self.new_portal_substrate(st, dt, eid, tbparams) 1616 myname = "%stunnel" % dt 1617 desthost = "%stunnel" % st 1618 1619 portal = self.new_portal_node(st, dt, tbparams, master, 1620 eid, myname, desthost, "control", 1621 ((tsubstrate.name,(('portal','true'),)),)) 1622 if self.fedkit: 1623 self.add_kit(portal, self.fedkit) 1624 if self.gatewaykit: 1625 self.add_kit(portal, self.gatewaykit) 1626 1627 topo[st].substrates.append(tsubstrate) 1628 topo[st].elements.append(segment_element) 1629 topo[st].elements.append(portal) 1630 1631 def new_dragon_portal(self, st, dt, master, eid, dip, idx, 1632 substrate, tbparams): 1633 # Add to the master testbed 1634 myname = "%stunnel" % dt 1635 desthost = "%s" % ip_addr(dip) 1636 1637 portal = self.new_portal_node(st, dt, tbparams, master, 1638 eid, myname, desthost, "control", 1639 ((substrate.name,( 1640 ('portal','true'), 1641 ('ip4_address', "%s" % ip_addr(dip)), 1642 ('dragon_vlan', 'unassigned%d' % idx), 1643 ('dragon_type', 'link'),)),)) 1644 if self.fedkit: 1645 self.add_kit(portal, self.fedkit) 1646 if self.gatewaykit: 1647 self.add_kit(portal, self.gatewaykit) 1648 1649 return portal 1650 1651 def add_portals(self, top, topo, eid, master, tbparams, ip_allocator): 1378 1652 """ 1379 1653 For each substrate in the main topology, find those that … … 1397 1671 continue 1398 1672 1399 # More than one testbed is on this substrate. Insert 1400 # some portals into the subtopologies. st == source testbed, 1401 # dt == destination testbed. 1402 for st in tbs.keys(): 1403 if not segment_substrate.has_key(st): 1404 segment_substrate[st] = { } 1405 if not portals.has_key(st): 1406 portals[st] = { } 1407 for dt in [ t for t in tbs.keys() if t != st]: 1408 sproject = tbparams[st].get('project', 'project') 1409 dproject = tbparams[dt].get('project', 'project') 1410 mproject = tbparams[master].get('project', 'project') 1411 sdomain = tbparams[st].get('domain', ".example.com") 1412 ddomain = tbparams[dt].get('domain', ".example.com") 1413 mdomain = tbparams[master].get('domain', '.example.com') 1414 muser = tbparams[master].get('user', 'root') 1415 smbshare = tbparams[master].get('smbshare', 'USERS') 1416 aid = tbparams[dt]['allocID']['fedid'] 1417 if st == master or dt == master: 1418 active = ("%s" % (st == master)) 1419 else: 1420 active = ("%s" %(st > dt)) 1421 if not segment_substrate[st].has_key(dt): 1422 # Put a substrate and a segment for the connected 1423 # testbed in there. 1424 tsubstrate, segment_element = \ 1425 self.new_portal_substrate(st, dt, eid, tbparams) 1426 segment_substrate[st][dt] = tsubstrate 1427 topo[st].substrates.append(tsubstrate) 1428 topo[st].elements.append(segment_element) 1429 1430 new_portal = False 1431 if portals[st].has_key(dt): 1432 # There's a portal set up to go to this destination. 1433 # See if there's room to multiples this connection on 1434 # it. If so, add an interface to the portal; if not, 1435 # set up to add a portal below. 1436 # [This little festival of braces is just a pop of the 1437 # last element in the list of portals between st and 1438 # dt.] 1439 portal = portals[st][dt][-1] 1440 mux = len([ i for i in portal.interface \ 1441 if not i.get_attribute('portal')]) 1442 if mux == self.muxmax: 1443 new_portal = True 1444 portal_type = "experiment" 1445 myname = "%stunnel%d" % (dt, len(portals[st][dt])) 1446 desthost = "%stunnel%d" % (st, len(portals[st][dt])) 1447 else: 1448 new_i = topdl.Interface( 1449 substrate=s.name, 1450 attribute=[ 1451 topdl.Attribute( 1452 attribute='ip4_address', 1453 value=tbs[dt] 1454 ) 1455 ]) 1456 portal.interface.append(new_i) 1457 else: 1458 # First connection to this testbed, make an empty list 1459 # and set up to add the new portal below 1460 new_portal = True 1461 portals[st][dt] = [ ] 1462 myname = "%stunnel%d" % (dt, len(portals[st][dt])) 1463 desthost = "%stunnel%d" % (st, len(portals[st][dt])) 1464 1465 if dt == master or st == master: portal_type = "both" 1466 else: portal_type = "experiment" 1467 1468 if new_portal: 1469 portal = self.new_portal_node(st, dt, tbparams, 1470 master, eid, myname, desthost, portal_type, 1471 segment_substrate[st][dt].name, s.name, tbs[dt]) 1472 if self.fedkit: 1473 self.add_kit(portal, self.fedkit) 1474 if self.gatewaykit: 1475 self.add_kit(portal, self.gatewaykit) 1476 1477 topo[st].elements.append(portal) 1478 portals[st][dt].append(portal) 1673 # DRAGON will not create multi-site vlans yet 1674 if len(tbs) == 2 and \ 1675 all([tbparams[x].has_key('dragon') for x in tbs]): 1676 self.create_dragon_substrate(s, topo, tbs, tbparams, 1677 master, eid) 1678 else: 1679 self.insert_internet_portals(s, topo, tbs, tbparams, master, 1680 eid, segment_substrate, portals) 1479 1681 1480 1682 # Make sure that all the slaves have a control portal back to the … … 1486 1688 e.get_attribute('portal_type') == 'both']) == 0: 1487 1689 1488 # Add to the master testbed 1489 tsubstrate, segment_element = \ 1490 self.new_portal_substrate(master, tb, eid, tbparams) 1491 myname = "%stunnel" % tb 1492 desthost = "%stunnel" % master 1493 1494 portal = self.new_portal_node(master, tb, tbparams, master, 1495 eid, myname, desthost, "control", tsubstrate.name) 1496 if self.fedkit: 1497 self.add_kit(portal, self.fedkit) 1498 if self.gatewaykit: 1499 self.add_kit(portal, self.gatewaykit) 1500 1501 topo[master].substrates.append(tsubstrate) 1502 topo[master].elements.append(segment_element) 1503 topo[master].elements.append(portal) 1504 1505 # And to the other testbed 1506 1507 tsubstrate, segment_element = \ 1508 self.new_portal_substrate(tb, master, eid, tbparams) 1509 myname = "%stunnel" % master 1510 desthost = "%stunnel" % tb 1511 1512 portal = self.new_portal_node(tb, master, tbparams, master, 1513 eid, myname, desthost, "control", tsubstrate.name) 1514 if self.fedkit: 1515 self.add_kit(portal, self.fedkit) 1516 if self.gatewaykit: 1517 self.add_kit(portal, self.gatewaykit) 1518 1519 topo[tb].substrates.append(tsubstrate) 1520 topo[tb].elements.append(segment_element) 1521 topo[tb].elements.append(portal) 1522 1690 if tbparams[master].has_key('dragon') \ 1691 and tbparams[tb].has_key('dragon'): 1692 1693 idx = len([x for x in topo.keys() \ 1694 if x.startswith('dragon')]) 1695 dip, leng = ip_allocator.allocate(4) 1696 dip += 1 1697 csub = topdl.Substrate( 1698 name="dragon-control-%s" % tb, 1699 capacity=topdl.Capacity(100000.0, 'max'), 1700 attribute=[ 1701 topdl.Attribute( 1702 attribute='portal', 1703 value='true' 1704 ) 1705 ] 1706 ) 1707 seg = topdl.Segment( 1708 id= tbparams[master]['allocID'], 1709 type='emulab', 1710 uri = self.tbmap.get(master, None), 1711 interface=[ 1712 topdl.Interface( 1713 substrate=csub.name), 1714 ], 1715 attribute = [ 1716 topdl.Attribute(attribute=n, value=v) 1717 for n, v in (\ 1718 ('domain', 1719 tbparams[master].get('domain', 1720 ".example.com")), 1721 ('experiment', "%s/%s" % \ 1722 (tbparams[master].get( 1723 'project', 1724 'project'), 1725 eid)),) 1726 ], 1727 ) 1728 topo[tb].substrates.append(csub) 1729 topo[tb].elements.append( 1730 self.new_dragon_portal(tb, master, master, eid, 1731 dip, idx, csub, tbparams)) 1732 topo[tb].elements.append(seg) 1733 1734 dip+=1 1735 mcsub = csub.clone() 1736 seg = topdl.Segment( 1737 id= tbparams[tb]['allocID'], 1738 type='emulab', 1739 uri = self.tbmap.get(tb, None), 1740 interface=[ 1741 topdl.Interface( 1742 substrate=csub.name), 1743 ], 1744 attribute = [ 1745 topdl.Attribute(attribute=n, value=v) 1746 for n, v in (\ 1747 ('domain', 1748 tbparams[tb].get('domain', 1749 ".example.com")), 1750 ('experiment', "%s/%s" % \ 1751 (tbparams[tb].get('project', 1752 'project'), 1753 eid)),) 1754 ], 1755 ) 1756 topo[master].substrates.append(mcsub) 1757 topo[master].elements.append( 1758 self.new_dragon_portal(master, tb, master, eid, 1759 dip, idx, mcsub, tbparams)) 1760 topo[master].elements.append(seg) 1761 1762 self.create_dragon_substrate(csub, topo, 1763 {tb: 1, master:1}, tbparams, master, eid) 1764 else: 1765 self.add_control_portal(master, tb, master, eid, topo, 1766 tbparams) 1767 self.add_control_portal(tb, master, master, eid, topo, 1768 tbparams) 1523 1769 1524 1770 # Connect the portal nodes into the topologies and clear out … … 1715 1961 top = topdl.topology_from_xml(file=split_data, top="experiment") 1716 1962 1717 hosts = self.allocate_ips_to_topo(top)1963 hosts, ip_allocator = self.allocate_ips_to_topo(top) 1718 1964 # Find the testbeds to look up 1719 1965 testbeds = set([ a.value for e in top.elements \ … … 1759 2005 self.auth.set_attribute(asignee, "%s/%s" % (configpath, f)) 1760 2006 1761 self.add_portals(top, topo, eid, master, tbparams) 2007 self.add_portals(top, topo, eid, master, tbparams, ip_allocator) 2008 # Now get access to the dynamic testbeds 2009 for k, t in topo.items(): 2010 if not t.get_attribute('dynamic'): 2011 continue 2012 tb = t.get_attribute('testbed') 2013 if tb: 2014 self.get_access(tb, None, user, tbparams, master, 2015 export_project, access_user) 2016 tbparams[k] = tbparams[tb] 2017 del tbparams[tb] 2018 allocated[k] = 1 2019 else: 2020 raise service_error(service_error.internal, 2021 "Dynamic allocation from no testbed!?") 2022 1762 2023 self.wrangle_software(expid, top, topo, tbparams) 1763 2024 … … 1769 2030 tbparams[k]['federant'] = {\ 1770 2031 'name': [ { 'localname' : eid} ],\ 1771 'emulab': tbparams[k]['emulab'],\1772 2032 'allocID' : tbparams[k]['allocID'],\ 1773 2033 'master' : k == master,\ 1774 2034 } 2035 if tbparams[k].has_key('emulab'): 2036 tbparams[k]['federant']['emulab'] = \ 2037 tbparams[k]['emulab'] 1775 2038 1776 2039 self.state_lock.acquire() … … 2019 2282 if rv.has_key('federant'): del rv['federant'] 2020 2283 else: 2021 # remove the allocationID info from each federant2284 # remove the allocationID and uri info from each federant 2022 2285 for f in rv.get('federant', []): 2023 2286 if f.has_key('allocID'): del f['allocID'] 2287 if f.has_key('uri'): del f['uri'] 2024 2288 return rv 2025 2289 … … 2156 2420 for fed in fed_exp.get('federant', []): 2157 2421 try: 2158 tb = fed[' emulab']['project']['testbed']['localname']2422 tb = fed['uri'] 2159 2423 aid = fed['allocID'] 2160 2424 except KeyError, e: -
fedd/federation/topdl.py
radcbdaf r69692a9 22 22 elif getattr(a, '__iter__', None): return a 23 23 else: return [ a ] 24 25 def remove_attribute(self, key): 26 to_del = None 27 attrs = getattr(self, 'attribute', []) 28 for i, a in enumerate(attrs): 29 if a.attribute == key: 30 to_del = i 31 break 32 33 if to_del: del attrs[i] 24 34 25 35 def get_attribute(self, key): … … 384 394 return e 385 395 386 def __init__(self, substrates=[], elements=[] ):396 def __init__(self, substrates=[], elements=[], attribute=[]): 387 397 self.substrates = [ self.init_class(Substrate, s) \ 388 398 for s in self.make_list(substrates) ] 389 399 self.elements = [ self.init_element(e) \ 390 400 for e in self.make_list(elements) ] 401 self.attribute = [ self.init_class(Attribute, c) \ 402 for c in self.make_list(attribute) ] 391 403 self.incorporate_elements() 392 404 … … 419 431 def clone(self): 420 432 return Topology(substrates=[s.clone() for s in self.substrates], 421 elements=[e.clone() for e in self.elements]) 433 elements=[e.clone() for e in self.elements], 434 attribute=[a.clone() for a in self.attribute]) 422 435 423 436 … … 432 445 if self.elements: 433 446 rv['elements'] = [ s.to_dict() for s in self.elements ] 447 if self.attribute: 448 rv['attribute'] = [ s.to_dict() for s in self.attribute] 434 449 return rv 435 450 … … 519 534 520 535 for k in e.keys(): 521 if isinstance(e[k], (basestring, int, float, long)):536 if isinstance(e[k], basestring): 522 537 rv += "<%s>%s</%s>" % (k, escape(e[k]), k) 538 elif isinstance(e[k], (int, float, long)): 539 rv += "<%s>%d</%s>" % (k, e[k], k) 523 540 elif isinstance(e[k], dict): 524 541 rv += "<%s>%s</%s>" % (k, dict_to_xml(e[k]), k) … … 530 547 rv += "<%s>%s</%s>" % (k, escape(ee), k) 531 548 else: 532 raise ConsistencyError("What is this?? %s %s" % (k, e[k])) 549 try: 550 rv += "<%s>%s</%s>" % (k, e[k], k) 551 except Exception: 552 raise ConsistencyError("What is this?? %s %s" % (k, e[k])) 533 553 if top: rv += "</%s>" % top 534 554 return rv … … 582 602 return t 583 603 584 def generate_portal_command_filter(cmd ):604 def generate_portal_command_filter(cmd, add_filter=None): 585 605 def rv(e): 586 606 s ="" 587 607 if isinstance(e, Computer): 588 608 gw = e.get_attribute('portal') 589 if gw: 609 if add_filter and callable(add_filter): 610 add = add_filter(e) 611 else: 612 add = True 613 if gw and add: 590 614 s = "%s $%s\n" % (cmd, to_tcl_name(e.name[0])) 591 615 return s
Note: See TracChangeset
for help on using the changeset viewer.