Keep FastAPI as the only backend; add media upload, ntfy hook, and PB collection bootstrap for production. Co-authored-by: Cursor <cursoragent@cursor.com>
87 lines
3.2 KiB
Python
87 lines
3.2 KiB
Python
"""One-time production setup: S3 identity, API env, PocketBase collections."""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import secrets
|
|
import sys
|
|
|
|
import paramiko
|
|
|
|
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
|
|
|
|
HOST = "107.173.30.245"
|
|
USER = "root"
|
|
PASS = "Xiao4669805"
|
|
REMOTE = "/opt/nomadweb"
|
|
|
|
|
|
def run(client: paramiko.SSHClient, cmd: str, timeout: int = 120) -> tuple[int, str]:
|
|
print(">>", cmd[:180])
|
|
_, stdout, stderr = client.exec_command(cmd, timeout=timeout)
|
|
out = stdout.read().decode("utf-8", errors="replace")
|
|
err = stderr.read().decode("utf-8", errors="replace")
|
|
code = stdout.channel.recv_exit_status()
|
|
if out.strip():
|
|
print(out[-3000:])
|
|
if err.strip():
|
|
print("ERR:", err[-1000:])
|
|
return code, out
|
|
|
|
|
|
def main() -> None:
|
|
s3_secret = secrets.token_urlsafe(24)
|
|
client = paramiko.SSHClient()
|
|
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
client.connect(HOST, username=USER, password=PASS, timeout=25)
|
|
|
|
# Add nomadweb S3 identity if missing
|
|
_, s3_raw = run(client, "cat /etc/seaweedfs/s3.json")
|
|
s3_cfg = json.loads(s3_raw)
|
|
identities = s3_cfg.get("identities", [])
|
|
nomadweb_id = next((i for i in identities if i.get("name") == "nomadweb"), None)
|
|
if nomadweb_id:
|
|
creds = (nomadweb_id.get("credentials") or [{}])[0]
|
|
s3_secret = creds.get("secretKey") or s3_secret
|
|
print("S3 identity nomadweb already exists")
|
|
else:
|
|
identities.append({
|
|
"name": "nomadweb",
|
|
"credentials": [{"accessKey": "nomadweb", "secretKey": s3_secret}],
|
|
"actions": ["Admin", "Read", "Write", "List", "Tagging"],
|
|
})
|
|
s3_cfg["identities"] = identities
|
|
payload = json.dumps(s3_cfg, indent=2)
|
|
run(client, f"cat > /etc/seaweedfs/s3.json <<'EOF'\n{payload}\nEOF")
|
|
run(client, "systemctl restart seaweed-s3.service")
|
|
print("S3 identity nomadweb created")
|
|
|
|
# Patch nomadro-api.env (idempotent keys)
|
|
patch = {
|
|
"POCKETBASE_URL": "http://127.0.0.1:8090",
|
|
"POCKETBASE_ADMIN_EMAIL": "admin@nomadro.com",
|
|
"POCKETBASE_ADMIN_PASSWORD": "Xiao4669805",
|
|
"S3_ENABLED": "true",
|
|
"S3_ENDPOINT": "http://127.0.0.1:8333",
|
|
"S3_PUBLIC_URL": "https://s3.nomadro.com",
|
|
"S3_ACCESS_KEY": "nomadweb",
|
|
"S3_SECRET_KEY": s3_secret,
|
|
"S3_BUCKET": "nomadweb",
|
|
"S3_REGION": "us-east-1",
|
|
"S3_UPLOAD_PREFIX": "nomadweb",
|
|
"NTFY_ENABLED": "true",
|
|
"NTFY_URL": "http://127.0.0.1:2586",
|
|
}
|
|
py = "import pathlib\np=pathlib.Path('/opt/nomadweb/deploy/nomadro-api.env')\ntext=p.read_text(encoding='utf-8') if p.exists() else ''\nlines=text.splitlines()\nkeys={}\nfor k,v in " + repr(list(patch.items())) + ":\n found=False\n for i,line in enumerate(lines):\n if line.startswith(k+'='):\n lines[i]=k+'='+v\n found=True\n break\n if not found:\n lines.append(k+'='+v)\np.write_text('\\n'.join(lines).rstrip()+'\\n', encoding='utf-8')\n"
|
|
run(client, f"python3 -c {json.dumps(py)}")
|
|
|
|
# Fix systemd PB password
|
|
run(client, "sed -i 's/POCKETBASE_ADMIN_PASSWORD=admin123456/POCKETBASE_ADMIN_PASSWORD=Xiao4669805/' /etc/systemd/system/nomadro-api.service")
|
|
run(client, "systemctl daemon-reload")
|
|
|
|
client.close()
|
|
print("\nProduction env patched. Run deploy_update.py to pull code + init PB.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|