[4700b3b] | 1 | #!/usr/local/bin/python |
---|
| 2 | |
---|
| 3 | import os,sys |
---|
| 4 | |
---|
| 5 | from ZSI import * |
---|
| 6 | from M2Crypto import SSL |
---|
| 7 | from M2Crypto.SSL.SSLServer import SSLServer |
---|
| 8 | import M2Crypto.httpslib |
---|
| 9 | |
---|
| 10 | import xml.parsers.expat |
---|
| 11 | |
---|
| 12 | import re |
---|
| 13 | import random |
---|
| 14 | import string |
---|
| 15 | import subprocess |
---|
| 16 | import tempfile |
---|
| 17 | import copy |
---|
| 18 | import pickle |
---|
| 19 | |
---|
| 20 | import traceback |
---|
| 21 | |
---|
| 22 | from threading import * |
---|
| 23 | |
---|
| 24 | from subprocess import * |
---|
| 25 | |
---|
| 26 | from fedd_services import * |
---|
| 27 | from fedd_internal_services import * |
---|
| 28 | from fedd_util import * |
---|
| 29 | import parse_detail |
---|
| 30 | from service_error import * |
---|
| 31 | |
---|
| 32 | import logging |
---|
| 33 | |
---|
| 34 | class nullHandler(logging.Handler): |
---|
| 35 | def emit(self, record): pass |
---|
| 36 | |
---|
| 37 | fl = logging.getLogger("fedd.experiment_control") |
---|
| 38 | fl.addHandler(nullHandler()) |
---|
| 39 | |
---|
| 40 | class fedd_split_local: |
---|
| 41 | def __init__(self, config=None): |
---|
| 42 | """ |
---|
| 43 | Intialize the various attributes, most from the config object |
---|
| 44 | """ |
---|
| 45 | self.debug = config.create_debug |
---|
| 46 | self.log = logging.getLogger("fedd.splitter") |
---|
| 47 | self.tclsh = "/usr/local/bin/otclsh" |
---|
| 48 | self.tcl_splitter = "/usr/testbed/lib/ns2ir/parse.tcl" |
---|
| 49 | self.trace_file = sys.stderr |
---|
| 50 | |
---|
| 51 | # Dispatch tables |
---|
| 52 | self.soap_services = {\ |
---|
| 53 | 'Ns2Split': make_soap_handler(\ |
---|
| 54 | Ns2SplitRequestMessage.typecode, |
---|
| 55 | getattr(self, "run_splitter"), |
---|
| 56 | Ns2SplitResponseMessage, |
---|
| 57 | "Ns2SplitResponseBody"), |
---|
| 58 | } |
---|
| 59 | |
---|
| 60 | self.xmlrpc_services = {\ |
---|
| 61 | 'Ns2Split': make_xmlrpc_handler(\ |
---|
| 62 | getattr(self, "run_splitter"), |
---|
| 63 | "Ns2SplitResponseBody"), |
---|
| 64 | } |
---|
| 65 | |
---|
| 66 | def run_splitter(self, req, fid): |
---|
| 67 | """ |
---|
| 68 | The external interface to experiment creation called from the |
---|
| 69 | dispatcher. |
---|
| 70 | |
---|
| 71 | Creates a working directory, splits the incoming description using the |
---|
| 72 | splitter script and parses out the avrious subsections using the |
---|
| 73 | lcasses above. Once each sub-experiment is created, use pooled threads |
---|
| 74 | to instantiate them and start it all up. |
---|
| 75 | """ |
---|
| 76 | try: |
---|
| 77 | tmpdir = tempfile.mkdtemp(prefix="split-") |
---|
| 78 | except IOError: |
---|
| 79 | raise service_error(service_error.internal, "Cannot create tmp dir") |
---|
| 80 | |
---|
| 81 | tclfile = tmpdir + "/experiment.tcl" |
---|
| 82 | pid = "dummy" |
---|
| 83 | gid = "dummy" |
---|
| 84 | |
---|
| 85 | req = req.get('Ns2SplitRequestBody', None) |
---|
| 86 | if not req: |
---|
| 87 | raise service_error(service_error.req, |
---|
| 88 | "Bad request format (no Ns2SplitRequestBody)") |
---|
| 89 | # The tcl parser needs to read a file so put the content into that file |
---|
| 90 | descr=req.get('experimentdescription', None) |
---|
| 91 | if descr: |
---|
| 92 | file_content=descr.get('ns2description', None) |
---|
| 93 | if file_content: |
---|
| 94 | try: |
---|
| 95 | f = open(tclfile, 'w') |
---|
| 96 | f.write(file_content) |
---|
| 97 | f.close() |
---|
| 98 | except IOError: |
---|
| 99 | raise service_error(service_error.internal, |
---|
| 100 | "Cannot write temp experiment description") |
---|
| 101 | else: |
---|
| 102 | raise service_error(service_error.req, |
---|
| 103 | "Only ns2descriptions supported") |
---|
| 104 | else: |
---|
| 105 | raise service_error(service_error.req, "No experiment description") |
---|
| 106 | |
---|
| 107 | master = req.get('master', None) |
---|
| 108 | if master == None: |
---|
| 109 | raise service_error(service_error.req, "No master testbed label") |
---|
| 110 | |
---|
| 111 | |
---|
| 112 | tclcmd = [self.tclsh, self.tcl_splitter, '-s', '-x', |
---|
| 113 | str(self.muxmax), '-m', master, pid, gid, eid, tclfile] |
---|
| 114 | tclparser = Popen(tclcmd, stdout=PIPE) |
---|
| 115 | |
---|
| 116 | # Package up the split data |
---|
| 117 | for line in tclparser.stdout: |
---|
| 118 | out += line |
---|
| 119 | |
---|
| 120 | # Walk up tmpdir, deleting as we go |
---|
| 121 | for path, dirs, files in os.walk(tmpdir, topdown=False): |
---|
| 122 | for f in files: |
---|
| 123 | os.remove(os.path.join(path, f)) |
---|
| 124 | for d in dirs: |
---|
| 125 | os.rmdir(os.path.join(path, d)) |
---|
| 126 | os.rmdir(tmpdir) |
---|
| 127 | |
---|
| 128 | resp = { 'output' : out } |
---|
| 129 | |
---|
| 130 | return resp |
---|
| 131 | |
---|
| 132 | |
---|