source: fedd/federation/split.py @ 3159f5d

axis_examplecompt_changesinfo-opsversion-3.01version-3.02
Last change on this file since 3159f5d was 3159f5d, checked in by Ted Faber <faber@…>, 14 years ago

Set up the repote splitter to translate into a topdl description. It has thus
become misnamed.

  • Property mode set to 100644
File size: 4.3 KB
RevLine 
[4700b3b]1#!/usr/local/bin/python
2
3import os,sys
4import subprocess
5import tempfile
[c971895]6import logging
[3159f5d]7import topdl
[4700b3b]8
[ec4fb42]9from util import *
[51cc9df]10from fedid import fedid
[9460b1e]11from remote_service import xmlrpc_handler, soap_handler
[4700b3b]12from service_error import *
[05191a6]13from authorizer import authorizer
[4700b3b]14
15
16class nullHandler(logging.Handler):
17    def emit(self, record): pass
18
[2c6128f]19fl = logging.getLogger("fedd.splitter")
[4700b3b]20fl.addHandler(nullHandler())
21
[ec4fb42]22class split_local:
[3f6bc5f]23    def __init__(self, config=None, auth=None):
[4700b3b]24        """
25        Intialize the various attributes, most from the config object
26        """
[05191a6]27        self.debug = config.getboolean("splitter", "debug")
28        self.muxmax = config.getint("splitter", "muxmax", 3)
29        self.tclsh = config.get("splitter", "tclsh", 
30                "/usr/local/bin/otclsh")
31        self.tcl_splitter = config.get("splitter", "tcl_splitter",
32                "/usr/testbed/lib/ns2ir/parse.tcl")
[61c71bf]33        access_db = config.get("splitter", "accessdb", None)
[05191a6]34        allow_any = config.getboolean("splitter", "allow_any", False)
[f4f4117]35
[4700b3b]36        self.log = logging.getLogger("fedd.splitter")
[c971895]37        set_log_level(config, "splitter", self.log)
[4700b3b]38        self.trace_file = sys.stderr
39
[2c6128f]40        set_log_level(config, "splitter", self.log)
[05191a6]41
42        if auth:
43            self.auth= auth
44        else:
45            self.auth = authorizer()
46            self.log.warning("[splitter] No authorizer passed in, " +\
47                    "using local one")
48
49        if access_db and allow_any: 
50            raise service_error(service_error.internal, 
51                    "Cannot specify both an access database and allow_any " +\
52                            "for splitter")
53       
54        if access_db:
55            try:
56                read_simple_accessdb(access_db, self.auth, 'split')
57            except IOError, e:
58                raise service_error(service_error.internal,
59                        "Error reading accessDB %s: %s" % (access_db, e))
60            except ValueError:
61                raise service_error(service_error.internal, "%s" % e)
62        elif allow_any:
63            auth.set_global_attribute("split")
64
65
[4700b3b]66        # Dispatch tables
67        self.soap_services = {\
[f069052]68                'Ns2Split': soap_handler("Ns2Split", self.run_splitter),
[4700b3b]69        }
70
71        self.xmlrpc_services = {\
[f069052]72                'Ns2Split': xmlrpc_handler('Ns2Split', self.run_splitter),
[4700b3b]73        }
74
75    def run_splitter(self, req, fid):
76        """
77        The external interface to experiment creation called from the
78        dispatcher.
79
80        Creates a working directory, splits the incoming description using the
81        splitter script and parses out the avrious subsections using the
82        lcasses above.  Once each sub-experiment is created, use pooled threads
83        to instantiate them and start it all up.
84        """
[05191a6]85
86        if not self.auth.check_attribute(fid, 'split'):
87            raise service_error(service_error.access, "Access Denied")
88
[4700b3b]89        try:
90            tmpdir = tempfile.mkdtemp(prefix="split-")
91        except IOError:
92            raise service_error(service_error.internal, "Cannot create tmp dir")
93
94        tclfile = tmpdir + "/experiment.tcl"
95        pid = "dummy"
96        gid = "dummy"
[f4f4117]97        eid = "dummy"
[4700b3b]98
99        req = req.get('Ns2SplitRequestBody', None)
100        if not req:
101            raise service_error(service_error.req,
102                    "Bad request format (no Ns2SplitRequestBody)")
103        # The tcl parser needs to read a file so put the content into that file
[f4f4117]104        descr=req.get('description', None)
[4700b3b]105        if descr:
106            file_content=descr.get('ns2description', None)
107            if file_content:
108                try:
109                    f = open(tclfile, 'w')
110                    f.write(file_content)
111                    f.close()
112                except IOError:
113                    raise service_error(service_error.internal,
114                            "Cannot write temp experiment description")
115            else:
116                raise service_error(service_error.req, 
117                        "Only ns2descriptions supported")
118        else:
[f4f4117]119            raise service_error(service_error.req, "No description")
[4700b3b]120
121        master = req.get('master', None)
122        if master == None:
123            raise service_error(service_error.req, "No master testbed label")
124       
[2c6128f]125        include_fedkit = req.get('include_fedkit', None)
126        if include_fedkit == None:
127            raise service_error(service_error.req, 
128                    "No federation kit inclusion directive")
129       
[4700b3b]130       
[3159f5d]131        tclcmd = [self.tclsh, self.tcl_splitter, '-t', '-x', 
[2c6128f]132            str(self.muxmax), '-m', master]
133        if include_fedkit: tclcmd.append('-k')
134        tclcmd.extend([pid, gid, eid, tclfile])
135        self.log.debug("Calling splitter %s" % " ".join(tclcmd))
[c971895]136        tclparser = subprocess.Popen(tclcmd, stdout=subprocess.PIPE)
[4700b3b]137
[3159f5d]138        top = topdl.topology_from_xml(file=tclparser.stdout, top="experiment")
[4700b3b]139
140        # Walk up tmpdir, deleting as we go
141        for path, dirs, files in os.walk(tmpdir, topdown=False):
142            for f in files:
143                os.remove(os.path.join(path, f))
144            for d in dirs:
145                os.rmdir(os.path.join(path, d))
146        os.rmdir(tmpdir)
147
[3159f5d]148        resp = { 
149                'experimentdescription':  { 
150                    'topdldescription': top.to_dict(),
151                    }
152                }
[4700b3b]153
154        return resp
155
156
Note: See TracBrowser for help on using the repository browser.