diff options
Diffstat (limited to 'scripts/swig_bot_lib/server.py')
| -rw-r--r-- | scripts/swig_bot_lib/server.py | 138 | 
1 files changed, 138 insertions, 0 deletions
| diff --git a/scripts/swig_bot_lib/server.py b/scripts/swig_bot_lib/server.py new file mode 100644 index 000000000000..cc25cee4d4b1 --- /dev/null +++ b/scripts/swig_bot_lib/server.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python + +""" +SWIG generation server.  Listens for connections from swig generation clients +and runs swig in the requested fashion, sending back the results. +""" + +# Future imports +from __future__ import absolute_import +from __future__ import print_function + +# Python modules +import argparse +import io +import logging +import os +import select +import shutil +import socket +import struct +import sys +import tempfile +import traceback + +# LLDB modules +import use_lldb_suite +from lldbsuite.support import fs +from lldbsuite.support import sockutil + +# package imports +from . import local +from . import remote + +default_port = 8537 + +def add_subparser_args(parser): +    parser.add_argument( +        "--port", +        action="store", +        default=default_port, +        help=("The local port to bind to")) + +    parser.add_argument( +        "--swig-executable", +        action="store", +        default=fs.find_executable("swig"), +        dest="swig_executable") + +def finalize_subparser_options(options): +    pass + +def initialize_listening_socket(options): +    logging.debug("Creating socket...") +    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + +    logging.info("Binding to ip address '', port {}".format(options.port)) +    s.bind(('', options.port)) + +    logging.debug("Putting socket in listen mode...") +    s.listen() +    return s + +def accept_once(sock, options): +    logging.debug("Waiting for connection...") +    while True: +        rlist, wlist, xlist = select.select([sock], [], [], 0.5) +        if not rlist: +            continue + +        client, addr = sock.accept() +        logging.info("Received connection from {}".format(addr)) +        data_size = struct.unpack("!I", sockutil.recvall(client, 4))[0] +        logging.debug("Expecting {} bytes of data from client" +                      .format(data_size)) +        data = sockutil.recvall(client, data_size) +        logging.info("Received {} bytes of data from client" +                     .format(len(data))) + +        pack_location = None +        try: +            tempfolder = os.path.join(tempfile.gettempdir(), "swig-bot") +            os.makedirs(tempfolder, exist_ok=True) + +            pack_location = tempfile.mkdtemp(dir=tempfolder) +            logging.debug("Extracting archive to {}".format(pack_location)) + +            local.unpack_archive(pack_location, data) +            logging.debug("Successfully unpacked archive...") + +            config_file = os.path.normpath(os.path.join(pack_location, +                                                        "config.json")) +            parsed_config = remote.parse_config(io.open(config_file)) +            config = local.LocalConfig() +            config.languages = parsed_config["languages"] +            config.swig_executable = options.swig_executable +            config.src_root = pack_location +            config.target_dir = os.path.normpath( +                os.path.join(config.src_root, "output")) +            logging.info( +                "Running swig.  languages={}, swig={}, src_root={}, target={}" +                .format(config.languages, config.swig_executable, +                        config.src_root, config.target_dir)) + +            status = local.generate(config) +            logging.debug("Finished running swig.  Packaging up files {}" +                          .format(os.listdir(config.target_dir))) +            zip_data = io.BytesIO() +            zip_file = local.pack_archive(zip_data, config.target_dir, None) +            response_status = remote.serialize_response_status(status) +            logging.debug("Sending response status {}".format(response_status)) +            logging.info("(swig output) -> swig_output.json") +            zip_file.writestr("swig_output.json", response_status) + +            zip_file.close() +            response_data = zip_data.getvalue() +            logging.info("Sending {} byte response".format(len(response_data))) +            client.sendall(struct.pack("!I", len(response_data))) +            client.sendall(response_data) +        finally: +            if pack_location is not None: +                logging.debug("Removing temporary folder {}" +                              .format(pack_location)) +                shutil.rmtree(pack_location) + +def accept_loop(sock, options): +    while True: +        try: +            accept_once(sock, options) +        except Exception as e: +            error = traceback.format_exc() +            logging.error("An error occurred while processing the connection.") +            logging.error(error) + +def run(options): +    print(options) +    sock = initialize_listening_socket(options) +    accept_loop(sock, options) +    return options | 
