source: fedd/federation/topdl.py @ ec9962b

axis_examplecompt_changesinfo-opsversion-3.01version-3.02
Last change on this file since ec9962b was 6d7a024, checked in by Ted Faber <faber@…>, 15 years ago

One more error.

  • Property mode set to 100644
File size: 23.0 KB
RevLine 
[eec716b]1#!/usr/local/bin/python
2
[6c57fe9]3import re
4
[eec716b]5class base:
6    @staticmethod
7    def init_class(c, arg):
8        if isinstance(arg, dict):
[df783c1]9            try:
10                return c(**arg)
11            except:
12                print "%s" % arg
13                raise
[eec716b]14        elif isinstance(arg, c):
15            return arg
16        else:
17            return None
18
19    @staticmethod
20    def make_list(a):
21        if isinstance(a, basestring) or isinstance(a, dict): return [ a ]
22        elif getattr(a, '__iter__', None): return a
23        else: return [ a ]
24
[69692a9]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]
34
[df783c1]35    def get_attribute(self, key):
36        rv = None
[db6b092]37        attrs = getattr(self, 'attribute', None)
[df783c1]38        if attrs:
39            for a in attrs:
40                if a.attribute == key:
41                    rv = a.value
42                    break
43        return rv
44
[6c57fe9]45    def set_attribute(self, key, value):
46        attrs = getattr(self, 'attribute', None)
47        if attrs is None:
48            return
49        for a in attrs:
50            if a.attribute == key: 
51                a.value = value
52                break
53        else:
54            attrs.append(Attribute(key, value))
[eec716b]55
56class ConsistencyError(RuntimeError): pass
[5b74b63]57class NamespaceError(RuntimeError): pass
[eec716b]58
59class Attribute(base):
60    def __init__(self, attribute, value):
61        self.attribute = attribute
62        self.value = value
63
[db6b092]64    def clone(self):
65        return Attribute(attribute=self.attribute, value=self.value)
66
[eec716b]67    def to_dict(self):
68        return { 'attribute': self.attribute, 'value': self.value }
69
70class Capacity(base):
71    def __init__(self, rate, kind):
[cc8d8e9]72        self.rate = float(rate)
[eec716b]73        self.kind = kind
74
[db6b092]75    def clone(self):
76        return Capacity(rate=self.rate, kind=self.kind)
77
[eec716b]78    def to_dict(self):
[cc8d8e9]79        return { 'rate': float(self.rate), 'kind': self.kind }
[eec716b]80
81class Latency(base):
82    def __init__(self, time, kind):
[cc8d8e9]83        self.time = float(time)
[eec716b]84        self.kind = kind
85
[db6b092]86    def clone(self):
87        return Latency(time=self.time, kind=self.kind)
88
[eec716b]89    def to_dict(self):
[cc8d8e9]90        return { 'time': float(self.time), 'kind': self.kind }
[eec716b]91
92class Substrate(base):
93    def __init__(self, name, capacity=None, latency=None, attribute=[]):
94        self.name = name
95        self.capacity = self.init_class(Capacity, capacity)
96        self.latency = self.init_class(Latency, latency)
97        self.attribute = [ self.init_class(Attribute, a) \
98                for a in self.make_list(attribute) ]
99        self.interfaces = [ ]
100
[db6b092]101    def clone(self):
102        if self.capacity: c = self.capacity.clone()
103        else: c = None
104
105        if self.latency: l = self.latency.clone()
106        else: l = None
107
108        return Substrate(name=self.name,
109                capacity=c,
110                latency=l,
111                attribute = [a.clone() for a in self.attribute])
112
[eec716b]113    def to_dict(self):
114        rv = { 'name': self.name }
115        if self.capacity:
116            rv['capacity'] = self.capacity.to_dict()
117        if self.latency:
118            rv['latency'] = self.latency.to_dict()
119        if self.attribute:
120            rv['attribute'] = [ a.to_dict() for a in self.attribute ]
121        return rv
122
123class CPU(base):
124    def __init__(self, type, attribute=[]):
125        self.type = type
126        self.attribute = [ self.init_class(Attribute, a) for a in \
127                self.make_list(attribute) ]
128
[db6b092]129    def clone(self):
130        return CPU(type=self.type,
131                attribute = [a.clone() for a in self.attribute])
132
[eec716b]133    def to_dict(self):
134        rv = { 'type': self.type}
135        if self.attribute:
136            rv['attribute'] = [ a.to_dict() for a in self.attribute ]
137        return rv
138
139class Storage(base):
140    def __init__(self, amount, persistence, attribute=[]):
[cc8d8e9]141        self.amount = float(amount)
[eec716b]142        self.presistence = persistence
143        self.attribute = [ self.init_class(Attribute, a) \
144                for a in self.make_list(attribute) ]
145
[db6b092]146    def clone(self):
147        return Storage(amount=self.amount, persistence=self.persistence, 
148                attribute = [a.clone() for a in self.attribute])
149
[eec716b]150    def to_dict(self):
151        rv = { 'amount': float(self.amount), 'persistence': self.persistence }
152        if self.attribute:
153            rv['attribute'] = [ a.to_dict() for a in self.attribute ]
154        return rv
155
156class OperatingSystem(base):
[df783c1]157    def __init__(self, name=None, version=None, distribution=None,
[eec716b]158            distributionversion=None, attribute=[]):
159        self.name = name
160        self.version = version
161        self.distribution = distribution
162        self.distributionversion = distributionversion
163        self.attribute = [ self.init_class(Attribute, a) \
164                for a in self.make_list(attribute) ]
165
[db6b092]166    def clone(self):
167        return OperatingSystem(name=self.name,
168                version=self.version,
169                distribution=self.distribution,
170                distributionversion=self.distributionversion,
171                attribute = [ a.clone() for a in self.attribute])
172
[eec716b]173    def to_dict(self):
[df783c1]174        rv = { }
175        if self.name: rv['name'] = self.name
[eec716b]176        if self.version: rv['version'] = self.version
177        if self.distribution: rv['version'] = self.distribution
178        if self.distributionversion: rv['version'] = self.distributionversion
179        if self.attribute:
180            rv['attribute'] = [ a.to_dict() for a in self.attribute ]
181        return rv
182
183class Software(base):
184    def __init__(self, location, install=None, attribute=[]):
185        self.location = location
186        self.install = install
187        self.attribute = [ self.init_class(Attribute, a)\
188                for a in self.make_list(attribute) ]
189
[db6b092]190    def clone(self):
191        return Software(location=self.location, install=self.install, 
192                attribute=[a.clone() for a in self.attribute])
193
[eec716b]194    def to_dict(self):
195        rv = { 'location': self.location }
196        if self.install: rv['install'] = self.install
197        if self.attribute:
198            rv['attribute'] = [ a.to_dict() for a in self.attribute ]
199        return rv
200
201class Interface(base):
[5b74b63]202    def __init__(self, substrate, name=None, capacity=None, latency=None,
203            attribute=[], element=None):
204        self.name = name
[cdb62d9]205        self.substrate = self.make_list(substrate)
[eec716b]206        self.capacity = self.init_class(Capacity, capacity)
207        self.latency = self.init_class(Latency, latency)
208        self.attribute = [ self.init_class(Attribute, a) \
209                for a in self.make_list(attribute) ]
210        self.element = element
211        self.subs = [ ]
212
[db6b092]213    def clone(self):
214        if self.capacity: c = self.capacity.clone()
215        else: c = None
216
217        if self.latency: l = self.latency.clone()
218        else: l = None
219
[d2471df]220        return Interface(substrate=[s for s in self.substrate], name=self.name,
[db6b092]221                capacity=c, latency=l,
222                attribute = [ a.clone() for a in self.attribute])
223
[eec716b]224    def to_dict(self):
[5b74b63]225        rv = { 'substrate': self.substrate, 'name': self.name }
[eec716b]226        if self.capacity:
227            rv['capacity'] = self.capacity.to_dict()
228        if self.latency:
229            rv['latency'] = self.latency.to_dict()
230        if self.attribute:
231            rv['attribute'] = [ a.to_dict() for a in self.attribute ]
232        return rv
233
[6c57fe9]234class ID(base):
235    def __init__(self, fedid=None, uuid=None, uri=None, localname=None,
236            kerberosUsername=None):
237        self.fedid=fedid
238        self.uuid = uuid
239        self.uri = uri
240        self.localname = localname
241        self.kerberosUsername = kerberosUsername
242
243    def clone(self):
244        return ID(self.fedid, self.uuid, self.uri, self.localname,
[ecca6eb]245                self.kerberosUsername)
[6c57fe9]246
247    def to_dict(self):
248        rv = { }
249        if self.fedid: rv['fedid'] = self.fedid
250        if self.uuid: rv['uuid'] = self.uuid
251        if self.uri: rv['uri'] = self.uri
252        if self.localname: rv['localname'] = self.localname
253        if self.kerberosUsername: rv['kerberosUsername'] = self.kerberosUsername
254        return rv
255
[eec716b]256class Computer(base):
[822fd49]257    def __init__(self, name, cpu=[], os=[], software=[], storage=[],
[cdb62d9]258            interface=[], attribute=[]):
[eec716b]259        def assign_element(i):
260            i.element = self
261
[1e7f268]262        self.name = name
[eec716b]263        self.cpu = [ self.init_class(CPU, c)  for c in self.make_list(cpu) ]
264        self.os = [ self.init_class(OperatingSystem, c) \
265                for c in self.make_list(os) ]
266        self.software = [ self.init_class(Software, c) \
267                for c in self.make_list(software) ]
268        self.storage = [ self.init_class(Storage, c) \
269                for c in self.make_list(storage) ]
270        self.interface = [ self.init_class(Interface, c) \
271                for c in self.make_list(interface) ]
272        self.attribute = [ self.init_class(Attribute, a) \
273                for a in self.make_list(attribute) ]
274        map(assign_element, self.interface)
275
[db6b092]276    def clone(self):
[d2471df]277        # Copy the list of names
[1e7f268]278        return Computer(name=self.name,
[db6b092]279                cpu=[x.clone() for x in self.cpu],
280                os=[x.clone() for x in self.os],
281                software=[x.clone() for x in self.software],
282                storage=[x.clone() for x in self.storage],
283                interface=[x.clone() for x in self.interface],
284                attribute=[x.clone() for x in self.attribute])
285
[eec716b]286    def to_dict(self):
287        rv = { }
[db6b092]288        if self.name:
[6d7a024]289            rv['name'] = self.name
[eec716b]290        if self.cpu:
291            rv['cpu'] = [ c.to_dict() for  c in self.cpu ]
292        if self.os:
293            rv['os'] = [ o.to_dict() for o in self.os ]
294        if self.software:
295            rv['software'] = [ s.to_dict() for s in self.software ]
296        if self.storage:
297            rv['storage'] = [ s.to_dict for s in self.storage ]
298        if self.interface:
299            rv['interface'] = [ i.to_dict() for i in self.interface ]
300        if self.attribute:
301            rv['attribute'] = [ i.to_dict() for i in self.attribute ]
[cdb62d9]302        return { 'computer': rv }
[eec716b]303
[6c57fe9]304
305class Testbed(base):
306    def __init__(self, uri, type, interface=[], attribute=[]):
307        self.uri = uri
308        self.type = type
309        self.interface = [ self.init_class(Interface, c) \
310                for c in self.make_list(interface) ]
311        self.attribute = [ self.init_class(Attribute, c) \
312                for c in self.make_list(attribute) ]
313
314    def clone(self):
315        return Testbed(self.uri, self.type,
316                interface=[i.clone() for i in self.interface],
317                attribute=[a.cone() for a in self.attribute])
318
319    def to_dict(self):
320        rv = { }
321        if self.uri: rv['uri'] = self.uri
322        if self.type: rv['type'] = self.type
323        if self.interface:
324            rv['interface'] = [ i.to_dict() for i in self.interface]
325        if self.attribute:
326            rv['attribute'] = [ a.to_dict() for a in self.attribute]
327        return { 'testbed': rv }
328
329class Segment(base):
330    def __init__(self, id, type, uri, interface=[], attribute=[]):
331        self.id = self.init_class(ID, id)
332        self.type = type
333        self.uri = uri
334        self.interface = [ self.init_class(Interface, c) \
335                for c in self.make_list(interface) ]
336        self.attribute = [ self.init_class(Attribute, c) \
337                for c in self.make_list(attribute) ]
338
339    def clone(self):
340        return Segment(self.id.clone(), self.type, self.uri, 
341                interface=[i.clone() for i in self.interface], 
[ecca6eb]342                attribute=[a.clone() for a in self.attribute])
[6c57fe9]343
344    def to_dict(self):
345        rv = { }
346        if self.id: rv['id'] = self.id.to_dict()
347        if self.type: rv['type'] = self.type
348        if self.uri: rv['uri'] = self.uri
349        if self.interface:
350            rv['interface'] = [ i.to_dict() for i in self.interface ]
351        if self.attribute:
352            rv['attribute'] = [ a.to_dict() for a in self.attribute ]
353        return { 'segment': rv }
354
355
[eec716b]356class Other(base):
357    def __init__(self, interface=[], attribute=[]):
358        self.interface = [ self.init_class(Interface, c) \
359                for c in self.make_list(interface) ]
360        self.attribute = [ self.init_class(Attribute, c) \
361                for c in self.make_list(attribute) ]
362
[db6b092]363    def clone(self):
364        return Other(interface=[i.clone() for i in self.interface], 
365                attribute=[a.clone() for a in attribute])
366
[eec716b]367    def to_dict(self):
[6c57fe9]368        rv = {}
[eec716b]369        if self.interface:
370            rv['interface'] = [ i.to_dict() for i in self.interface ]
371        if self.attribute:
372            rv['attribute'] = [ a.to_dict() for a in self.attribute ]
[6c57fe9]373        return {'other': rv }
[eec716b]374
375
376class Topology(base):
377    @staticmethod
378    def init_element(e):
379        """
380        e should be of the form { typename: args } where args is a dict full of
381        the right parameters to initialize the element.  e should have only one
382        key, but we walk e's keys in an arbitrary order and instantiate the
383        first key we know how to.
384        """
385        classmap = {
386                'computer': Computer,
[6c57fe9]387                'testbed': Testbed,
388                'segment': Segment,
[eec716b]389                'other': Other,
390            }
391
[db6b092]392        if isinstance(e, dict):
393            for k in e.keys():
394                cl = classmap.get(k, None)
395                if cl: return cl(**e[k])
396        else:
397            return e
[eec716b]398
[69692a9]399    def __init__(self, substrates=[], elements=[], attribute=[]):
[eec716b]400        self.substrates = [ self.init_class(Substrate, s) \
401                for s in self.make_list(substrates) ]
402        self.elements = [ self.init_element(e) \
403                for e in self.make_list(elements) ]
[69692a9]404        self.attribute = [ self.init_class(Attribute, c) \
405                for c in self.make_list(attribute) ]
[db6b092]406        self.incorporate_elements()
407
[5b74b63]408    @staticmethod
409    def name_element_interfaces(e):
410        names = set([i.name for i in e.interface if i.name])
411        inum = 0
412        for i in [ i for i in e.interface if not i.name]:
413            while inum < 1000:
414                n = "inf%03d" % inum
415                inum += 1
416                if n not in names:
417                    i.name = n
418                    break
419            else:
420                raise NamespaceError("Cannot make new interface name")
421
422
423
424    def name_interfaces(self):
425        """
426        For any interface without a name attribute, assign a unique one within
427        its element.
428        """
429
430        for e in self.elements:
431            self.name_element_interfaces(e)
432
433
[db6b092]434    def incorporate_elements(self):
435
[eec716b]436        # Could to this init in one gulp, but we want to look for duplicate
437        # substrate names
438        substrate_map = { }
439        for s in self.substrates:
[db6b092]440            s.interfaces = [ ]
[eec716b]441            if not substrate_map.has_key(s.name):
442                substrate_map[s.name] = s
443            else:
444                raise ConsistencyError("Duplicate substrate name %s" % s.name)
445
446        for e in self.elements:
[5b74b63]447            self.name_element_interfaces(e)
[eec716b]448            for i in e.interface:
[db6b092]449                i.element = e
450                i.subs = [ ]
[eec716b]451                for sn in i.substrate:
452                    # NB, interfaces have substrate names in their substrate
453                    # attribute.
454                    if substrate_map.has_key(sn):
455                        sub = substrate_map[sn]
456                        i.subs.append(sub)
457                        sub.interfaces.append(i)
458                    else:
459                        raise ConsistencyError("No such substrate for %s" % sn)
460
[db6b092]461    def clone(self):
462        return Topology(substrates=[s.clone() for s in self.substrates], 
[69692a9]463                elements=[e.clone() for e in self.elements],
464                attribute=[a.clone() for a in self.attribute])
[db6b092]465
466
467    def make_indices(self):
468        sub_index = dict([(s.name, s) for s in self.substrates])
469        elem_index = dict([(n, e) for e in self.elements for n in e.name])
470
[eec716b]471    def to_dict(self):
472        rv = { }
473        if self.substrates:
474            rv['substrates'] = [ s.to_dict() for s in self.substrates ]
475        if self.elements:
476            rv['elements'] = [ s.to_dict() for s in self.elements ]
[69692a9]477        if self.attribute:
478            rv['attribute'] = [ s.to_dict() for s in self.attribute]
[eec716b]479        return rv
480
[db6b092]481def topology_from_xml(string=None, file=None, filename=None, top="topology"):
[eec716b]482    import xml.parsers.expat
483
484    class parser:
485        def __init__(self):
486            self.stack = [ ]
487            self.chars = ""
488            self.key = ""
489            self.have_chars = False
490            self.current = { }
491            self.in_cdata = False
492       
493        def start_element(self, name, attrs):
494            self.chars = ""
495            self.have_chars = False
496            self.key = str(name)
497            self.stack.append((self.current, self.key))
498            self.current = { }
499
500        def end_element(self, name):
501            if self.have_chars:
502                self.chars = self.chars.strip()
503                if len(self.chars) >0:
504                    addit = self.chars
505                else:
506                    addit = self.current
507            else:
508                addit = self.current
509
510            parent, key = self.stack.pop()
511            if parent.has_key(key):
512                if isinstance(parent[key], list):
513                    parent[key].append(addit)
514                else:
515                    parent[key] = [parent[key], addit]
516            else:
517                parent[key] = addit
518            self.current = parent
519            self.key = key
520
521            self.chars = ""
522            self.have_chars = False
523
524        def char_data(self, data):
525            self.have_chars = True
526            self.chars += data
527
528    p = parser()
529    xp = xml.parsers.expat.ParserCreate()
530
531    xp.StartElementHandler = p.start_element
532    xp.EndElementHandler = p.end_element
533    xp.CharacterDataHandler = p.char_data
534
[db6b092]535    num_set = len([ x for x in (string, filename, file)\
536            if x is not None ])
537
538    if num_set != 1:
539        raise RuntimeError("Exactly one one of file, filename and string " + \
540                "must be set")
541    elif filename:
542        f = open(filename, "r")
[df783c1]543        xp.ParseFile(f)
[cc8d8e9]544        f.close()
[db6b092]545    elif file:
546        xp.ParseFile(file)
[df783c1]547    elif string:
548        xp.Parse(string, isfinal=True)
549    else:
550        return None
[eec716b]551
552    return Topology(**p.current[top])
553
554def topology_to_xml(t, top=None):
555    """
556    Print the topology as XML.  This is quick and dirty, but should work for
557    many purposes.  Convert the topology to a dict and print it recursively.
558    """
559    from xml.sax.saxutils import escape
560
561    def dict_to_xml(e, top=None):
562        if top: rv = "<%s>" % top
563        else: rv = ""
564
565        for k in e.keys():
[69692a9]566            if isinstance(e[k], basestring):
[eec716b]567                rv += "<%s>%s</%s>" % (k, escape(e[k]), k)
[69692a9]568            elif isinstance(e[k], (int, float, long)):
569                rv += "<%s>%d</%s>" % (k, e[k], k)
[eec716b]570            elif isinstance(e[k], dict):
571                rv += "<%s>%s</%s>" % (k, dict_to_xml(e[k]), k)
572            elif getattr(e[k], '__iter__', None):
573                for ee in e[k]:
574                    if isinstance(ee, dict):
575                        rv += "<%s>%s</%s>" % (k, dict_to_xml(ee), k)
576                    else:
577                        rv += "<%s>%s</%s>" % (k, escape(ee), k)
578            else:
[69692a9]579                try:
580                    rv += "<%s>%s</%s>" % (k, e[k], k)
581                except Exception:
582                    raise ConsistencyError("What is this?? %s %s" % (k, e[k]))
[eec716b]583        if top: rv += "</%s>" % top
584        return rv
585
586    return dict_to_xml(t.to_dict(), top)
587
588
[db6b092]589def topology_to_vtopo(t):
590    nodes = [ ]
591    lans = [ ]
[eec716b]592
[db6b092]593    for eidx, e in enumerate(t.elements):
594        if e.name: name = e.name[0]
595        else: name = "unnamed_node%d" % eidx
596       
597        ips = [ ]
[cc8d8e9]598        for idx, i in enumerate(e.interface):
[db6b092]599            ip = i.get_attribute('ip4_address')
600            ips.append(ip)
601            port = "%s:%d" % (name, idx)
602            for idx, s in enumerate(i.subs):
603                bw = 100000
604                delay = 0.0
605                if s.capacity:
606                    bw = s.capacity.rate
607                if i.capacity:
608                    bw = i.capacity.rate
609
610                if s.latency:
611                    delay = s.latency.time
612                if i.latency:
613                    bw = i.latency.time
614
615                lans.append({
616                    'member': port,
617                    'vname': s.name,
618                    'ip': ip,
619                    'vnode': name,
620                    'delay': delay,
621                    'bandwidth': bw,
622                    })
623        nodes.append({
624            'ips': ":".join(ips),
625            'vname': name,
626            })
627
[cc8d8e9]628    return { 'node': nodes, 'lan': lans }
629
[6c57fe9]630def to_tcl_name(n):
[8483f24]631    t = re.sub('-(\d+)', '(\\1)', n)
[6c57fe9]632    return t
633
[69692a9]634def generate_portal_command_filter(cmd, add_filter=None):
[ecca6eb]635    def rv(e):
636        s =""
637        if isinstance(e, Computer):
638            gw = e.get_attribute('portal')
[69692a9]639            if add_filter and callable(add_filter):
640                add = add_filter(e)
641            else:
642                add = True
643            if gw and add:
[1e7f268]644                s = "%s ${%s}\n" % (cmd, to_tcl_name(e.name))
[ecca6eb]645        return s
646    return rv
647
[6c57fe9]648def generate_portal_image_filter(image):
649    def rv(e):
650        s =""
651        if isinstance(e, Computer):
652            gw = e.get_attribute('portal')
653            if gw:
[1e7f268]654                s = "tb-set-node-os ${%s} %s\n" % (to_tcl_name(e.name), image)
[6c57fe9]655        return s
656    return rv
657
[ecca6eb]658def generate_portal_hardware_filter(type):
[6c57fe9]659    def rv(e):
660        s =""
661        if isinstance(e, Computer):
662            gw = e.get_attribute('portal')
663            if gw:
[1e7f268]664                s = "tb-set-hardware ${%s} %s\n" % (to_tcl_name(e.name), type)
[6c57fe9]665        return s
666    return rv
667
668
[d46b1d5]669def topology_to_ns2(t, filters=[], routing="Manual"):
[cc8d8e9]670    out = """
671set ns [new Simulator]
672source tb_compat.tcl
673
674"""
[6c57fe9]675
[cc8d8e9]676    for e in t.elements:
677        rpms = ""
678        tarfiles = ""
679        if isinstance(e, Computer):
[1e7f268]680            name = to_tcl_name(e.name)
[cc8d8e9]681            out += "set %s [$ns node]\n" % name
682            if e.os and len(e.os) == 1:
683                osid = e.os[0].get_attribute('osid')
684                if osid:
[d46b1d5]685                    out += "tb-set-node-os ${%s} %s\n" % (name, osid)
[ecca6eb]686            hw = e.get_attribute('type')
687            if hw:
[d46b1d5]688                out += "tb-set-hardware ${%s} %s\n" % (name, hw)
[cc8d8e9]689            for s in e.software:
690                if s.install:
691                    tarfiles += "%s %s " % (s.install, s.location)
692                else:
693                    rpms += "%s " % s.location
694            if rpms:
[d46b1d5]695                out += "tb-set-node-rpms ${%s} %s\n" % (name, rpms)
[cc8d8e9]696            if tarfiles:
[d46b1d5]697                out += "tb-set-node-tarfiles ${%s} %s\n" % (name, tarfiles)
[cc8d8e9]698            startcmd = e.get_attribute('startup')
699            if startcmd:
[d46b1d5]700                out+= 'tb-set-node-startcmd ${%s} "%s"\n' % (name, startcmd)
[6c57fe9]701            for f in filters:
702                out += f(e)
[cc8d8e9]703            out+= "\n"
704   
705    for idx, s in enumerate(t.substrates):
706        loss = s.get_attribute('loss')
707        if s.latency:
708            delay = s.latency.time
709        else:
710            delay = 0
[6c57fe9]711        name = to_tcl_name(s.name or "sub%d" % idx)
[cc8d8e9]712
713        if len(s.interfaces) > 2:
714            # Lan
[d46b1d5]715            members = [ to_tcl_name("${%s}") % i.element.name[0] \
[6c57fe9]716                    for i in s.interfaces]
717            out += 'set %s [$ns make-lan "%s" %fkb %fms ]\n' % \
[cc8d8e9]718                    (name, " ".join(members), s.capacity.rate, delay)
719            if loss:
[d46b1d5]720                "tb-set-lan-loss ${%s} %f\n" % (name, float(loss))
[cc8d8e9]721
722            for i in s.interfaces:
723                e = i.element
[1da6a23]724                ip = i.get_attribute("ip4_address")
[cc8d8e9]725                if ip:
[d46b1d5]726                    out += "tb-set-ip-lan ${%s} ${%s} %s\n" % \
[430e98d]727                            (to_tcl_name(e.name[0]), name, ip)
[cc8d8e9]728                if i.capacity and i.capacity.rate != s.capacity.rate:
[d46b1d5]729                    out += "tb-set-node-lan-bandwidth ${%s} ${%s} %fkb\n" % \
[6c57fe9]730                            (to_tcl_name(e.name[0]), name, i.capacity.rate)
[cc8d8e9]731                if i.latency and i.latency.time != delay:
[d46b1d5]732                    out += "tb-set-node-lan-delay ${%s} ${%s} %fms\n" % \
[6c57fe9]733                            (to_tcl_name(e.name[0]), name, i.latency.time)
[cc8d8e9]734                iloss = i.get_attribute('loss')
735                if loss and iloss != loss :
[d46b1d5]736                    out += "tb-set-node-lan-loss ${%s} ${%s} %f\n" % \
[6c57fe9]737                            (to_tcl_name(e.name[0]), name, float(loss))
[cc8d8e9]738            out+= "\n"
739        elif len(s.interfaces) == 2:
740            f = s.interfaces[0]
741            t = s.interfaces[1]
742
[d46b1d5]743            out += "set %s [$ns duplex-link ${%s} ${%s} %fkb %fms DropTail]\n" %\
[6c57fe9]744                    (name, to_tcl_name(f.element.name[0]), 
745                            to_tcl_name(t.element.name[0]),
[cc8d8e9]746                            s.capacity.rate, delay)
747            if loss:
[d46b1d5]748                out += "tb-set-link-loss ${%s} %f\n" % (name, float(loss))
[cc8d8e9]749
750            for i in s.interfaces:
751                lloss = i.get_attribute("loss")
752                cap_override = i.capacity and \
753                        i.capacity.rate != s.capacity.rate
754                delay_override = i.latency and \
755                        i.latency.time != delay
756                loss_override = lloss and lloss != loss
757                if cap_override or delay_override or loss_override:
758                    if i.capacity: cap = i.capacity.rate
759                    else: cap = s.capacity.rate
760
761                    if i.latency: delay = i.latency.time
762
763                    if lloss: loss = lloss
764                    else: loss = loss or 0.0
765
[d46b1d5]766                    out += "tb-set-link-simplex-params ${%s} ${%s} %fms %fkb %f\n"\
[6c57fe9]767                            % (name, to_tcl_name(i.element.name[0]),
768                                    delay, cap, loss)
[1da6a23]769                ip = i.get_attribute('ip4_address')
770                if ip:
[d46b1d5]771                    out += "tb-set-ip-link ${%s} ${%s} %s\n" % \
[1da6a23]772                            (to_tcl_name(i.element.name[0]), name, ip)
[cc8d8e9]773            out+= "\n"
[6c57fe9]774        for f in filters:
775            out+= f(s)
[1da6a23]776    out+="$ns rtproto %s" % routing
[cc8d8e9]777    out+="""
778$ns run
779"""
780    return out
[2fdf4b3]781
782def topology_to_rspec(t, filters=[]):
783    out = '<?xml version="1.0" encoding="UTF-8"?>\n' + \
784        '<rspec xmlns="http://www.protogeni.net/resources/rspec/0.1"\n' + \
785        '\txmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n' + \
786        '\txsi:schemaLocation="http://www.protogeni.net/resources/rspec/0.1 '+ \
787        'http://www.protogeni.net/resources/rspec/0.1/request.xsd"\n' + \
788        '\ttype="request" >\n'
789
790    ifname = { }
791    ifnode = { }
792
793    for e in [e for e in t.elements if isinstance(e, Computer)]:
[1e7f268]794        name = e.name
[2fdf4b3]795        virt_type = e.get_attribute("virtualization_type") or "emulab-vnode"
796        exclusive = e.get_attribute("exclusive") or "1"
797        hw = e.get_attribute("type") or "pc";
798        slots = e.get_attribute("slots") or "1";
799        startup = e.get_attribute("startup")
[f81aba7]800        # XXX: unreliable on ProtoGENI 20100303
801        #tarfiles = " ".join([ "%s %s" % (s.install, s.location) \
802        #       for s in e.software if s.location and s.install ])
[2fdf4b3]803
804        extras = ""
805        if startup: extras += '\t\tstartup_command="%s"\n' % startup
[f81aba7]806        #if tarfiles: extras +='\t\ttarfiles="%s"\n' % tarfiles
[2fdf4b3]807        out += '\t<node virtual_id="%s"\n\t\tvirtualization_type="%s"\n' % \
808                (name, virt_type)
809        out += '\t\texclusive="%s"' % exclusive
810        if extras: out += '\n%s' % extras
811        out += '>\n'
812        out += '\t\t<node_type type_name="%s" slots="%s"/>\n' % (hw, slots)
813        for i, ii in enumerate(e.interface):
[5b74b63]814            out += '\t\t<interface virtual_id="%s"/>\n' % ii.name
[2fdf4b3]815            ifnode[ii] = name
816        for f in filters:
817            out += f(s)
818        out += '\t</node>\n'
819
820    for i, s in enumerate(t.substrates):
[f81aba7]821        if len(s.interfaces) == 0: 
822            continue
823        out += '\t<link virtual_id="%s" link_type="ethernet">\n' % s.name
[2fdf4b3]824        if s.capacity and s.capacity.kind == "max":
[f81aba7]825            bwout = True
826            out += '\t\t<bandwidth>%d</bandwidth>\n' % s.capacity.rate
827        else:
828            bwout = False
[2fdf4b3]829        if s.latency and s.latency.kind == "max":
[f81aba7]830            out += '\t\t<latency>%d</latency>\n' % s.latency.time
831        elif bwout:
832            out += '\t\t<latency>0</latency>\n'
[2fdf4b3]833        for ii in s.interfaces:
[6d07908]834            out += ('\t\t<interface_ref virtual_node_id="%s" ' + \
[5b74b63]835                    'virtual_interface_id="%s"/>\n') % (ifnode[ii], ii.name)
[2fdf4b3]836        for f in filters:
837            out += f(s)
838        out += '\t</link>\n'
839    out += '</rspec>\n'
840    return out
841
Note: See TracBrowser for help on using the repository browser.