source: fedd/fedd/split.py @ 05191a6

axis_examplecompt_changesinfo-opsversion-1.30version-2.00version-3.01version-3.02
Last change on this file since 05191a6 was 05191a6, checked in by Ted Faber <faber@…>, 15 years ago

All services use authorizer. Global authorization file, shared routine to read simple authorization files. Fixes some more partial state errors in experiment_control.

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