On Sat, 2020-05-30 at 19:41 +0200, Frédéric Mangano-Tarumi wrote: > aurweb.spawn used to launch only PHP’s built-in server. Now it spawns a > dummy FastAPI application too. Since both stacks spawn their own HTTP > server, aurweb.spawn also spawns nginx as a reverse proxy to mount them > under the same base URL, defined by aur_location in the configuration. > --- > TESTING | 3 +- > aurweb/asgi.py | 8 +++++ > aurweb/spawn.py | 80 +++++++++++++++++++++++++++++++++++++------- > conf/config.defaults | 7 ++++ > 4 files changed, 85 insertions(+), 13 deletions(-) > create mode 100644 aurweb/asgi.py > > diff --git a/TESTING b/TESTING > index a5e08cb8..31e3bcbd 100644 > --- a/TESTING > +++ b/TESTING > @@ -12,7 +12,8 @@ INSTALL. > 2) Install the necessary packages: > > # pacman -S --needed php php-sqlite sqlite words fortune-mod \ > - python python-sqlalchemy python-alembic > + python python-sqlalchemy python-alembic \ > + python-fastapi uvicorn nginx
Add this to .gitlab-ci.yml too. > > Ensure to enable the pdo_sqlite extension in php.ini. > > diff --git a/aurweb/asgi.py b/aurweb/asgi.py > new file mode 100644 > index 00000000..8d3deedc > --- /dev/null > +++ b/aurweb/asgi.py > @@ -0,0 +1,8 @@ > +from fastapi import FastAPI > + > +app = FastAPI() > + > + > [email protected]("/sso/") > +async def hello(): > + return {"message": "Hello from FastAPI!"} > diff --git a/aurweb/spawn.py b/aurweb/spawn.py > index 5fa646b5..df6a2ed5 100644 > --- a/aurweb/spawn.py > +++ b/aurweb/spawn.py > @@ -10,8 +10,10 @@ configuration anyway. > > import atexit > import argparse > +import os > import subprocess > import sys > +import tempfile > import time > import urllib > > @@ -20,6 +22,7 @@ import aurweb.schema > > > children = [] > +temporary_dir = None > verbosity = 0 > > > @@ -35,10 +38,42 @@ class ProcessExceptions(Exception): > super().__init__("\n- ".join(messages)) > > > +def generate_nginx_config(): > + """ > + Generate an nginx configuration based on aurweb's configuration. > + The file is generated under `temporary_dir`. > + Returns the path to the created configuration file. > + """ > + aur_location = aurweb.config.get("options", "aur_location") > + aur_location_parts = urllib.parse.urlsplit(aur_location) > + config_path = os.path.join(temporary_dir, "nginx.conf") > + config = open(config_path, "w") > + # We double nginx's braces because they conflict with Python's f-strings. > + config.write(f""" > + events {{}} > + daemon off; > + error_log /dev/stderr info; > + pid {os.path.join(temporary_dir, "nginx.pid")}; > + http {{ > + access_log /dev/stdout; > + server {{ > + listen {aur_location_parts.netloc}; > + location / {{ > + proxy_pass http://{aurweb.config.get("php", > "bind_address")}; > + }} > + location /sso {{ > + proxy_pass http://{aurweb.config.get("fastapi", > "bind_address")}; > + }} > + }} > + }} > + """) > + return config_path > + > + > def spawn_child(args): > """Open a subprocess and add it to the global state.""" > if verbosity >= 1: > - print(f"Spawning {args}", file=sys.stderr) > + print(f":: Spawning {args}", file=sys.stderr) > children.append(subprocess.Popen(args)) > > > @@ -52,10 +87,29 @@ def start(): > if children: > return > atexit.register(stop) > - aur_location = aurweb.config.get("options", "aur_location") > - aur_location_parts = urllib.parse.urlsplit(aur_location) > - htmldir = aurweb.config.get("options", "htmldir") > - spawn_child(["php", "-S", aur_location_parts.netloc, "-t", htmldir]) > + > + # Friendly message > + ruler = "-" * os.get_terminal_size().columns > + print(ruler) > + print("Spawing PHP and FastAPI, then nginx as a reverse proxy.") > + print("Check out " + aurweb.config.get("options", "aur_location")) > + print("Hit ^C to terminate everything.") > + print(ruler) I would have a single print statement and replace ^C with CTRL+C. But this is just a nitpick. > + > + # PHP > + php_address = aurweb.config.get("php", "bind_address") > + htmldir = aurweb.config.get("php", "htmldir") > + spawn_child(["php", "-S", php_address, "-t", htmldir]) > + > + # FastAPI > + host, port = aurweb.config.get("fastapi", "bind_address").rsplit(":", 1) > + spawn_child(["python", "-m", "uvicorn", > + "--host", host, > + "--port", port, > + "aurweb.asgi:app"]) > + > + # nginx > + spawn_child(["nginx", "-p", temporary_dir, "-c", > generate_nginx_config()]) > > > def stop(): > @@ -73,7 +127,7 @@ def stop(): > try: > p.terminate() > if verbosity >= 1: > - print(f"Sent SIGTERM to {p.args}", file=sys.stderr) > + print(f":: Sent SIGTERM to {p.args}", file=sys.stderr) > except Exception as e: > exceptions.append(e) > for p in children: > @@ -99,9 +153,11 @@ if __name__ == '__main__': > help='increase verbosity') > args = parser.parse_args() > verbosity = args.verbose > - start() > - try: > - while True: > - time.sleep(60) > - except KeyboardInterrupt: > - stop() > + with tempfile.TemporaryDirectory(prefix="aurweb-") as tmpdirname: > + temporary_dir = tmpdirname > + start() > + try: > + while True: > + time.sleep(60) > + except KeyboardInterrupt: > + stop() > diff --git a/conf/config.defaults b/conf/config.defaults > index 86fe765c..ed495168 100644 > --- a/conf/config.defaults > +++ b/conf/config.defaults > @@ -41,9 +41,16 @@ cache = none > cache_pkginfo_ttl = 86400 > memcache_servers = 127.0.0.1:11211 > > +[php] > +; Address PHP should bind when spawned in development mode by aurweb.spawn. > +bind_address = 127.0.0.1:8081 > ; Directory containing aurweb's PHP code, required by aurweb.spawn. > ;htmldir = /path/to/web/html > > +[fastapi] > +; Address uvicorn should bind when spawned in development mode by > aurweb.spawn. > +bind_address = 127.0.0.1:8082 > + > [ratelimit] > request_limit = 4000 > window_length = 86400 Otherwise, LGTM. Filipe Laíns
signature.asc
Description: This is a digitally signed message part
