Add support for exposing scripts as web endpoints, short-term for building images.
This commit is contained in:
@@ -5,6 +5,7 @@ import json
|
|||||||
import os
|
import os
|
||||||
import pyinotify
|
import pyinotify
|
||||||
import ssl
|
import ssl
|
||||||
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
@@ -51,6 +52,10 @@ parser.add_argument(
|
|||||||
dest='server_cert',
|
dest='server_cert',
|
||||||
action='store',
|
action='store',
|
||||||
required=True)
|
required=True)
|
||||||
|
parser.add_argument(
|
||||||
|
'--exec-handler',
|
||||||
|
dest='exec_handlers',
|
||||||
|
action='append')
|
||||||
FLAGS = parser.parse_args()
|
FLAGS = parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
@@ -184,11 +189,12 @@ class HTTPRequestHandler(object):
|
|||||||
}
|
}
|
||||||
_BLOCK_SIZE = 2 ** 16
|
_BLOCK_SIZE = 2 ** 16
|
||||||
|
|
||||||
def __init__(self, image_path, image_types, websockets):
|
def __init__(self, image_path, image_types, exec_handlers, websockets):
|
||||||
self._static_path = os.path.join(os.path.dirname(sys.argv[0]), 'static')
|
self._static_path = os.path.join(os.path.dirname(sys.argv[0]), 'static')
|
||||||
|
|
||||||
self._image_path = image_path
|
self._image_path = image_path
|
||||||
self._image_types = image_types
|
self._image_types = image_types
|
||||||
|
self._exec_handlers = exec_handlers
|
||||||
|
|
||||||
slave_ws_handler = GetSlaveWSHandler(image_types, websockets)
|
slave_ws_handler = GetSlaveWSHandler(image_types, websockets)
|
||||||
self._slave_ws_handler = wsgiutils.WebSocketWSGIApplication(
|
self._slave_ws_handler = wsgiutils.WebSocketWSGIApplication(
|
||||||
@@ -212,6 +218,9 @@ class HTTPRequestHandler(object):
|
|||||||
elif path.startswith('/static/'):
|
elif path.startswith('/static/'):
|
||||||
file_name = path[8:]
|
file_name = path[8:]
|
||||||
return self._ServeStaticFile(start_response, file_name)
|
return self._ServeStaticFile(start_response, file_name)
|
||||||
|
elif path.startswith('/exec/'):
|
||||||
|
method = path[6:]
|
||||||
|
return self._ServeExec(start_response, method, env['QUERY_STRING'])
|
||||||
elif path == '/ws/slave':
|
elif path == '/ws/slave':
|
||||||
return self._slave_ws_handler(env, start_response)
|
return self._slave_ws_handler(env, start_response)
|
||||||
elif path == '/ws/master':
|
elif path == '/ws/master':
|
||||||
@@ -259,10 +268,23 @@ class HTTPRequestHandler(object):
|
|||||||
start_response('404 Not found')
|
start_response('404 Not found')
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
def _ServeExec(self, start_response, method, arg):
|
||||||
|
handler = self._exec_handlers[method]
|
||||||
|
start_response('200 OK', [])
|
||||||
|
proc = subprocess.Popen(
|
||||||
|
[handler, arg],
|
||||||
|
stdout=subprocess.PIPE)
|
||||||
|
while True:
|
||||||
|
block = proc.stdout.read(self._BLOCK_SIZE)
|
||||||
|
if len(block) == 0:
|
||||||
|
break
|
||||||
|
yield block
|
||||||
|
proc.wait()
|
||||||
|
|
||||||
|
|
||||||
class Server(object):
|
class Server(object):
|
||||||
|
|
||||||
def __init__(self, listen_host, listen_port, server_key, server_cert, ca_cert, image_path, image_types):
|
def __init__(self, listen_host, listen_port, server_key, server_cert, ca_cert, image_path, image_types, exec_handlers):
|
||||||
websockets = WebSockets()
|
websockets = WebSockets()
|
||||||
|
|
||||||
wm = pyinotify.WatchManager()
|
wm = pyinotify.WatchManager()
|
||||||
@@ -272,7 +294,8 @@ class Server(object):
|
|||||||
type_path = os.path.join(image_path, image_type)
|
type_path = os.path.join(image_path, image_type)
|
||||||
wm.add_watch(type_path, pyinotify.IN_MOVED_TO)
|
wm.add_watch(type_path, pyinotify.IN_MOVED_TO)
|
||||||
|
|
||||||
http_handler = HTTPRequestHandler(image_path, image_types, websockets)
|
exec_handlers = dict(x.split('=', 1) for x in (exec_handlers or []))
|
||||||
|
http_handler = HTTPRequestHandler(image_path, image_types, exec_handlers, websockets)
|
||||||
self._httpd = geventserver.WSGIServer(
|
self._httpd = geventserver.WSGIServer(
|
||||||
(listen_host, listen_port),
|
(listen_host, listen_port),
|
||||||
http_handler,
|
http_handler,
|
||||||
@@ -297,7 +320,8 @@ def main():
|
|||||||
FLAGS.server_cert,
|
FLAGS.server_cert,
|
||||||
FLAGS.ca_cert,
|
FLAGS.ca_cert,
|
||||||
FLAGS.image_path,
|
FLAGS.image_path,
|
||||||
set(FLAGS.image_types))
|
set(FLAGS.image_types),
|
||||||
|
FLAGS.exec_handlers)
|
||||||
server.Serve()
|
server.Serve()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user