source: fedd/federation/split.py @ 59f3d1f

version-1.30
Last change on this file since 59f3d1f was 59f3d1f, checked in by Ted Faber <faber@…>, 15 years ago

whoops, broke ns_image

  • Property mode set to 100644
File size: 4.3 KB
Line 
1#!/usr/local/bin/python
2
3import os,sys
4import subprocess
5import tempfile
6import logging
7
8from util import *
9from fedid import fedid
10from remote_service import xmlrpc_handler, soap_handler
11from service_error import *
12from authorizer import authorizer
13
14
15class nullHandler(logging.Handler):
16    def emit(self, record): pass
17
18fl = logging.getLogger("fedd.splitter")
19fl.addHandler(nullHandler())
20
21class split_local:
22    def __init__(self, config=None, auth=None):
23        """
24        Intialize the various attributes, most from the config object
25        """
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", "accessdb", None)
33        allow_any = config.getboolean("splitter", "allow_any", False)
34
35        self.log = logging.getLogger("fedd.splitter")
36        set_log_level(config, "splitter", self.log)
37        self.trace_file = sys.stderr
38
39        set_log_level(config, "splitter", self.log)
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
65        # Dispatch tables
66        self.soap_services = {\
67                'Ns2Split': soap_handler("Ns2Split", self.run_splitter),
68        }
69
70        self.xmlrpc_services = {\
71                'Ns2Split': xmlrpc_handler('Ns2Split', self.run_splitter),
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        """
84
85        if not self.auth.check_attribute(fid, 'split'):
86            raise service_error(service_error.access, "Access Denied")
87
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"
96        eid = "dummy"
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
103        descr=req.get('description', None)
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:
118            raise service_error(service_error.req, "No description")
119
120        master = req.get('master', None)
121        if master == None:
122            raise service_error(service_error.req, "No master testbed label")
123       
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       
129       
130        tclcmd = [self.tclsh, self.tcl_splitter, '-s', '-x', 
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))
135        tclparser = subprocess.Popen(tclcmd, stdout=subprocess.PIPE,
136                close_fds=True, cwd=tmpdir)
137
138        out = ""
139        # Package up the split data
140        for line in tclparser.stdout:
141            out += line
142
143        # Walk up tmpdir, deleting as we go
144        for path, dirs, files in os.walk(tmpdir, topdown=False):
145            for f in files:
146                os.remove(os.path.join(path, f))
147            for d in dirs:
148                os.rmdir(os.path.join(path, d))
149        os.rmdir(tmpdir)
150
151        resp = { 'output' : out }
152
153        return resp
154
155
Note: See TracBrowser for help on using the repository browser.