Changeset 4d4dde4


Ignore:
Timestamp:
May 19, 2010 3:10:28 AM (14 years ago)
Author:
Ted Faber <faber@…>
Branches:
axis_example, compt_changes, info-ops, master, version-3.01, version-3.02
Children:
89e2138
Parents:
f9c2f63
Message:

Constraints come out of a component file now, and the clunky composition attributes are gone.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • fedd/compose.py

    rf9c2f63 r4d4dde4  
    66import random
    77import copy
     8
     9import xml.parsers.expat
    810
    911from optparse import OptionParser, OptionValueError
     
    2830                ",".join(self.provides), ",".join(self.accepts))
    2931
     32    def to_xml(self):
     33        rv = "<constraint>"
     34        if isinstance(self.name, tuple):
     35            rv += "<name>%s</name>" % self.name[0]
     36        else:
     37            rv += "<name>%s</name>" % self.name
     38        rv += "<required>%s</required>" % self.required
     39        for p in self.provides:
     40            rv += "<provides>%s</provides>" % p
     41        for a in self.accepts:
     42            rv += "<accepts>%s</accepts>" % a
     43        rv+= "</constraint>"
     44        return rv
     45
     46def constraints_from_xml(string=None, file=None, filename=None,
     47        top="constraints"):
     48    class parser:
     49        def __init__(self, top):
     50            self.top = top
     51            self.constraints = [ ]
     52            self.chars = None
     53            self.current = None
     54            self.in_top = False
    3055       
     56        def start_element(self, name, attrs):
     57            self.chars = None
     58            self.key = str(name)
     59
     60            if name == self.top:
     61                self.in_top = True
     62
     63            if self.in_top:
     64                if name == 'constraint':
     65                    self.current = constraint()
     66
     67        def end_element(self, name):
     68            if self.current:
     69                if self.chars is not None:
     70                    self.chars = self.chars.strip()
     71
     72                if name == 'required':
     73                    if self.chars is None:
     74                        self.current.required = False
     75                    else:
     76                        self.current.required = (self.chars.lower() == 'true')
     77                elif name == 'name':
     78                    self.current.name = self.chars
     79                elif name == 'accepts':
     80                    self.current.accepts.append(self.chars)
     81                elif name == 'provides':
     82                    self.current.provides.append(self.chars)
     83                elif name == 'constraint':
     84                    self.constraints.append(self.current)
     85                    self.current = None
     86                else:
     87                    print >>sys.stderr, \
     88                            "Unexpected element in constraint: %s" % name
     89            elif name == self.top:
     90                self.in_top = False
     91
     92
     93        def char_data(self, data):
     94            if self.in_top:
     95                if self.chars is None: self.chars = data
     96                else: self.chars += data
     97
     98    p = parser(top=top)
     99    xp = xml.parsers.expat.ParserCreate()
     100
     101    xp.StartElementHandler = p.start_element
     102    xp.EndElementHandler = p.end_element
     103    xp.CharacterDataHandler = p.char_data
     104
     105    if len([x for x in (string, filename, file) if x is not None])!= 1:
     106        raise RuntimeError("Exactly one one of file, filename and string " + \
     107                "must be set")
     108    elif filename:
     109        f = open(filename, "r")
     110        xp.ParseFile(f)
     111        f.close()
     112    elif file:
     113        xp.ParseFile(file)
     114    elif string:
     115        xp.Parse(string, isfinal=True)
     116    else:
     117        return []
     118
     119    return p.constraints
     120
     121
    31122class ComposeOptionParser(OptionParser):
    32123    """
     
    47138        self.add_option('--output', dest='outfile', default=None,
    48139                help='Output file name')
    49         self.add_option('--format', dest='format', default="xml",
    50                 help='Output file format')
     140        self.add_option("--format", dest="format", type="choice",
     141                choices=("xml", "topdl", "tcl", "ns"),
     142                help="Output file format")
    51143        self.add_option('--add_testbeds', dest='add_testbeds', default=False,
    52144                action='store_true',
     
    311403    return marks
    312404
    313 def add_constraint_attributes(top, marks):
    314     """
    315     Take the constraints in marks and add attributes representing them to the
    316     nodes in top.
    317     """
    318     for e in [e for e in top.elements if isinstance(e, topdl.Computer)]:
    319         if e.name in marks and not e.get_attribute('composition_point'):
    320             c = marks[e.name]
    321             e.set_attribute('composition_point', 'true')
    322             e.set_attribute('required', '%s' % c.required)
    323             e.set_attribute('provides', ",".join(c.provides))
    324             e.set_attribute('accepts', ",".join(c.accepts))
    325 
    326 def remove_constraint_attributes(top, marks):
    327     """
    328     Remove constraint attributes that match the ones in the dict from the
    329     topology.
    330     """
    331     for e in [e for e in top.elements \
    332             if isinstance(e, topdl.Computer) and e.name in marks]:
    333         e.remove_attribute('composition_point')
    334         e.remove_attribute('required')
    335         e.remove_attribute('provides')
    336         e.remove_attribute('accepts')
    337 
    338405def import_ns2_component(fn):
    339406    """
     
    353420    if not top:
    354421        raise RuntimeError("Cannot create topology from: %s" % fn)
    355     add_constraint_attributes(top, marks)
    356422
    357423    return (top, marks)
     
    367433    """
    368434    top = topdl.topology_from_xml(filename=fn, top='experiment')
    369     marks = { }
    370     for e in [ e for e in top.elements if isinstance(e, topdl.Computer)]:
    371         if e.get_attribute('composition_point'):
    372             r = e.get_attribute('required') or 'false'
    373             a = e.get_attribute('accepts')
    374             p = e.get_attribute('provides')
    375             if a and p:
    376                 c = constraint(name=e.name, required=(r == 'required'),
    377                     provides=p.split(','), accepts=a.split(','))
    378                 marks[e.name] = c
     435    cons = constraints_from_xml(filename=fn, top='constraints')
     436    marks= dict([(c.name, c ) for c in cons])
    379437    return (top, marks)
    380438
     
    410468        attributes should be in the topology.
    411469        """
     470        print >>f, "<component>"
     471        print >>f, "<constraints>"
     472        for c in constraints:
     473            print >>f, c.to_xml()
     474        print >>f, "</constraints>"
    412475        print >>f, topdl.topology_to_xml(comp, top='experiment')
     476        print >>f, "</component>"
    413477
    414478    def ns2_out(f, top, constraints):
     
    586650    connect_composition_points(comp, constraints, names)
    587651
    588     # Remove composition attributes for satisfied constraints
    589     remove_constraint_attributes(comp, dict(
    590         [(c.name[0], c) for c in constraints if c.match]))
    591 elif topos == 1:
     652elif components == 1:
    592653    comp = topos[0]
    593654    if opts.add_testbeds:
     
    598659    sys.exit("Did not read any components.")
    599660
    600 # Put out the composition with only the unmatched constriaints
     661# Put out the composition with only the unmatched constraints
    601662output_composition(comp, [c for c in constraints if not c.match],
    602663        opts.outfile, opts.format)
Note: See TracChangeset for help on using the changeset viewer.