summaryrefslogtreecommitdiff
path: root/scripts/swig_bot_lib/server.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/swig_bot_lib/server.py')
-rw-r--r--scripts/swig_bot_lib/server.py138
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 0000000000000..cc25cee4d4b1a
--- /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