Graceful exit when shell finish.

This commit is contained in:
Roberto Abdelkader Martínez Pérez
2019-04-30 09:32:16 +02:00
parent b0566e14a1
commit ad6ffb6bc4
+55 -27
View File
@@ -34,6 +34,7 @@ log = logging.getLogger('kapow')
# Resource Management # # Resource Management #
######################################################################## ########################################################################
CONNECTIONS = {} CONNECTIONS = {}
@@ -140,31 +141,48 @@ class ConnectionHandler:
async def get_resource(request): async def get_resource(request):
id = request.match_info["id"] id = request.match_info["id"]
resource = request.match_info["resource"] resource = request.match_info["resource"]
maybe_content = await CONNECTIONS[id].get(resource)
if isinstance(maybe_content, StreamReader): try:
content = maybe_content connection = CONNECTIONS[id]
response = web.StreamResponse(status=200, reason="OK") except KeyError:
await response.prepare(request) response = web.HTTPNotFound()
chunk = await content.readany()
while chunk:
await response.write(chunk)
chunk = await content.readany()
await response.write_eof()
return response
else: else:
body = maybe_content content = await connection.get(resource)
return web.Response(body=body)
if isinstance(content, StreamReader):
response = web.StreamResponse(status=200, reason="OK")
await response.prepare(request)
chunk = await content.readany()
while chunk:
await response.write(chunk)
chunk = await content.readany()
await response.write_eof()
else:
response = web.Response(body=content)
return response
async def set_resource(request): async def set_resource(request):
id = request.match_info["id"] id = request.match_info["id"]
resource = request.match_info["resource"] resource = request.match_info["resource"]
try: try:
await CONNECTIONS[id].set(resource, request.content) connection = CONNECTIONS[id]
except ConnectionResetError: except KeyError:
# Raised when trying to write to an already-closed stream. response = web.HTTPNotFound()
request.transport.close() else:
return web.Response(body=b'') try:
await connection.set(resource, request.content)
except ConnectionResetError:
# Raised when trying to write to an already-closed stream.
request.transport.close()
else:
response = web.Response(body=b'')
return response
async def append_resource(request): async def append_resource(request):
@@ -220,6 +238,7 @@ async def create_route(request):
handle_route(content["entrypoint"], handle_route(content["entrypoint"],
content["command"]), content["command"]),
name=name) name=name)
print(f'Route created {content["method"]} {content["url_pattern"]}')
return web.json_response(name) return web.json_response(name)
@@ -227,6 +246,7 @@ async def delete_route(request):
id = request.match_info["id"] id = request.match_info["id"]
route = request.app.router._named_resources.pop(id) route = request.app.router._named_resources.pop(id)
request.app.router._resources.remove(route) request.app.router._resources.remove(route)
print(f'Route deleted {id}')
return web.json_response(id) return web.json_response(id)
@@ -234,24 +254,32 @@ async def delete_route(request):
# aiohttp webapp # # aiohttp webapp #
######################################################################## ########################################################################
async def run_init_script():
if len(sys.argv) < 2:
raise RuntimeError("Script file is mandatory.")
async def run_init_script(app):
if len(sys.argv) == 1:
# No script given
cmd = "/bin/bash"
elif len(sys.argv) == 2:
cmd = f"/bin/bash --init-file {sys.argv[1]}"
else:
raise RuntimeError("Invalid parameter count.")
binpath = os.path.join(os.path.dirname(os.path.realpath(__file__)), "bin")
shell_task = await asyncio.create_subprocess_shell( shell_task = await asyncio.create_subprocess_shell(
f"/bin/bash --init-file {sys.argv[1]}", cmd,
# script,
# executable=os.environ.get('SHELL', '/bin/sh'),
env={**os.environ, env={**os.environ,
"KAPOW_URL": "http://localhost:8080/kapow", "KAPOW_URL": "http://localhost:8080/kapow",
"PATH": ":".join([os.path.join(os.path.dirname(os.path.realpath(__file__)), "bin"), "PATH": ":".join([binpath, os.environ["PATH"]]),
os.environ["PATH"]]),
}) })
await shell_task.wait() await shell_task.wait()
await app.cleanup()
os._exit(shell_task.returncode)
async def start_background_tasks(app): async def start_background_tasks(app):
app["debug_tasks"] = app.loop.create_task(run_init_script()) loop = asyncio.get_running_loop()
app["debug_tasks"] = loop.create_task(run_init_script(app))
def main(): def main():