"""Stop old API_System_Python on wakka-test-server and deploy guest-chat :7777 for test.pubuli.com.""" from __future__ import annotations import os import sys import paramiko HOST = "20.191.152.26" USER = "wakka" PASSWORD = os.environ["DEPLOY_PASSWORD"] REMOTE = "/home/wakka/guest-cs-stack" LOCAL = os.path.dirname(os.path.abspath(__file__)) COMPOSE = "docker-compose.chat.yaml -f docker-compose.chat.test7777.yaml" FILES = [ "docker-compose.chat.yaml", "docker-compose.chat.test7777.yaml", "chatwoot.env", "guest-cs.env", "guest-cs.test.env", "bootstrap-chatwoot-test.sh", ] def run(client: paramiko.SSHClient, cmd: str, timeout: int = 900) -> tuple[int, str]: print(">>>", cmd.split("\n")[0][:110]) _, 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: print(out) if err: print(err, file=sys.stderr) return code, out def main() -> int: client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(HOST, username=USER, password=PASSWORD, timeout=30) run(client, "hostname; screen -ls 2>/dev/null || true; ss -tlnp | grep -E '7777|7788' || true") stop_old = r""" set -e echo "[stop] old screen API_System_Python_7788..." screen -S API_System_Python_7788 -X quit 2>/dev/null || true for sid in $(screen -ls 2>/dev/null | awk '/API_System_Python/ {print $1}' | tr -d ')'); do screen -S "$sid" -X quit 2>/dev/null || true done pkill -f "API_System_Python" 2>/dev/null || true pkill -f "python app.py" 2>/dev/null || true pkill -f "python.*7788" 2>/dev/null || true pkill -f "python.*7777" 2>/dev/null || true fuser -k 7777/tcp 7788/tcp 2>/dev/null || true sleep 2 screen -ls 2>/dev/null || echo "no screen" ps aux | grep -E 'python.*app|API_System' | grep -v grep || echo "no old python" """ run(client, stop_old, timeout=120) run(client, f"mkdir -p {REMOTE}") sftp = client.open_sftp() for name in FILES: local = os.path.join(LOCAL, name) remote = f"{REMOTE}/{name}" with open(local, "rb") as fh: data = fh.read().replace(b"\r\n", b"\n") with sftp.file(remote, "w") as rf: rf.write(data) print("uploaded", name) sftp.close() deploy = f""" set -euo pipefail cd {REMOTE} chmod +x bootstrap-chatwoot-test.sh 2>/dev/null || true sudo docker pull ladioussuapp/guest-chat:latest sudo docker compose -f {COMPOSE} up -d --force-recreate guest-chat sleep 25 sudo docker compose -f {COMPOSE} ps curl -sI http://127.0.0.1:7777/guest-customer-service sudo docker exec guest-chat printenv CHATWOOT_GUEST_BASE_URL FRONTEND_URL CHATWOOT_GUEST_WEBSITE_TOKEN APP_PORT """ code, out = run(client, deploy, timeout=600) if "gunicorn" not in out.lower(): run(client, f"cd {REMOTE} && bash bootstrap-chatwoot-test.sh", timeout=300) token_cmd = ( "sudo docker exec guest-chat-postgres-1 psql -U postgres -d chatwoot_production -t -A " "-c \"SELECT website_token FROM channel_web_widgets LIMIT 1;\"" ) _, token_out = run(client, token_cmd, timeout=60) token = token_out.strip() if token: env_content = ( "# test.pubuli.com:7777\n" f"CHATWOOT_GUEST_WEBSITE_TOKEN={token}\n" "CHATWOOT_GUEST_BASE_URL=http://test.pubuli.com:7777/cw\n" ) sftp = client.open_sftp() with sftp.file(f"{REMOTE}/guest-cs.test.env", "w") as f: f.write(env_content) sftp.close() print("updated guest-cs.test.env token=", token) run(client, deploy, timeout=600) verify = """ curl -s http://127.0.0.1:7777/guest-customer-service | grep -o 'base_url[^,]*' | head -1 curl -s http://127.0.0.1:7777/guest-customer-service | grep -o 'guest_new_path[^,]*' | head -1 """ run(client, verify, timeout=60) client.close() return code if __name__ == "__main__": raise SystemExit(main())