Graceful exit when shell finish.
This commit is contained in:
@@ -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():
|
||||||
|
|||||||
Reference in New Issue
Block a user