Files
2026-08-15 14:51:51 +08:00

121 lines
4.1 KiB
Python

"""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())