mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-08-21 21:10:15 +00:00
106 lines
3.2 KiB
Python
Executable File
106 lines
3.2 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Save the relay address on first start, then exec the relay.
|
|
|
|
The address is printed only when it is created, and is not stored in the
|
|
database in its displayed form, so it is captured from the relay's output.
|
|
"""
|
|
import os
|
|
import shlex
|
|
import subprocess
|
|
import sys
|
|
|
|
BIN = "simplex-chat-relay"
|
|
WEB_ROOT = "/var/www/relay-web-channels"
|
|
ADDR_FILE = "/out/relay-address.txt"
|
|
CAPTURE_TIMEOUT = 180 # seconds
|
|
DEFAULT_RTS_OPTS = "-N -F1.2 -A16m -I0.01 -Iw15"
|
|
DEFAULT_POOL_SIZE = "4" # the binary defaults to a single connection
|
|
DEFAULT_QUEUE_SIZE = "65536"
|
|
|
|
|
|
def require(name):
|
|
value = os.environ.get(name)
|
|
if not value:
|
|
sys.exit(f"{name} is required")
|
|
return value
|
|
|
|
|
|
def rts_args():
|
|
"""RELAY_RTS_OPTS holds bare options; the +RTS/-RTS markers are added here."""
|
|
opts = [
|
|
o
|
|
for o in shlex.split(os.environ.get("RELAY_RTS_OPTS") or DEFAULT_RTS_OPTS)
|
|
if o not in ("+RTS", "-RTS")
|
|
]
|
|
return ["+RTS", *opts, "-RTS"] if opts else []
|
|
|
|
|
|
def find_address(text):
|
|
for token in text.split():
|
|
if token.startswith("https://") or token.startswith("simplex:"):
|
|
return token
|
|
return None
|
|
|
|
|
|
def capture_address(oneshot):
|
|
"""Create the address if needed and save it. Runs before the relay starts."""
|
|
cmd = oneshot + ["--create-schema", "-t", "0", "-e", "/sa"]
|
|
try:
|
|
out = subprocess.run(
|
|
cmd,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.STDOUT,
|
|
text=True,
|
|
errors="replace",
|
|
timeout=CAPTURE_TIMEOUT,
|
|
).stdout
|
|
except subprocess.TimeoutExpired as exc:
|
|
out = exc.stdout or ""
|
|
sys.stdout.write(out)
|
|
sys.stdout.flush()
|
|
|
|
address = find_address(out)
|
|
if address:
|
|
with open(ADDR_FILE, "w") as f:
|
|
f.write(address + "\n")
|
|
else:
|
|
sys.stderr.write("entrypoint: relay address not captured; will retry next start\n")
|
|
|
|
|
|
def main():
|
|
name = require("RELAY_NAME")
|
|
domain = require("RELAY_WEB_DOMAIN")
|
|
conn = require("DB_CONN")
|
|
image_file = os.environ.get("RELAY_IMAGE_FILE")
|
|
|
|
os.makedirs(f"{WEB_ROOT}/channel", exist_ok=True)
|
|
os.makedirs("/out", exist_ok=True)
|
|
|
|
common = [BIN, "--relay", "--headless", "--user-display-name", name]
|
|
|
|
# Only applied when the address is created, which the one-shot below does.
|
|
address_server = os.environ.get("RELAY_ADDRESS_SERVER")
|
|
if address_server:
|
|
common += ["--relay-address-server", address_server]
|
|
|
|
# The image is applied only when the profile is created.
|
|
if not os.path.exists(ADDR_FILE):
|
|
oneshot = common + (["--user-image-file", image_file] if image_file else []) + ["-d", conn]
|
|
capture_address(oneshot)
|
|
|
|
relay = common + [
|
|
"--relay-web-domain", domain,
|
|
"--relay-web-dir", f"{WEB_ROOT}/channel",
|
|
"--relay-web-cors-file", f"{WEB_ROOT}/cors.conf",
|
|
"--relay-web-interval", "30",
|
|
"-d", conn,
|
|
"--create-schema",
|
|
"--pool-size", os.environ.get("RELAY_POOL_SIZE") or DEFAULT_POOL_SIZE,
|
|
"--queue-size", os.environ.get("RELAY_QUEUE_SIZE") or DEFAULT_QUEUE_SIZE,
|
|
] + rts_args()
|
|
os.execvp(relay[0], relay)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|