130 lines
4.4 KiB
Python
Executable File
130 lines
4.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
from __future__ import annotations
|
|
|
|
import base64
|
|
import json
|
|
import os
|
|
import time
|
|
|
|
from tencentcloud.common import credential
|
|
from tencentcloud.common.profile.client_profile import ClientProfile
|
|
from tencentcloud.common.profile.http_profile import HttpProfile
|
|
from tencentcloud.tat.v20201028 import models as tat_models, tat_client
|
|
|
|
|
|
DEFAULT_INSTANCE_ID = os.environ.get("DEPLOY_INSTANCE_ID", "ins-ntmpcd3a")
|
|
DEFAULT_REGION = os.environ.get("DEPLOY_REGION", "me-saudi-arabia")
|
|
DEFAULT_REPO_URL = os.environ.get("MONITOR_REPO_URL", "git@gitea.haiyihy.com:hy/hy-app-monitor.git")
|
|
DEFAULT_REPO_REF = os.environ.get("MONITOR_REPO_REF", "main")
|
|
DEFAULT_REMOTE_DIR = os.environ.get("MONITOR_REMOTE_DIR", "/opt/hy-app-monitor")
|
|
DEFAULT_APP_PORT = os.environ.get("APP_PORT", "6666")
|
|
|
|
|
|
def env_required(name: str) -> str:
|
|
value = os.environ.get(name, "").strip()
|
|
if not value:
|
|
raise SystemExit(f"missing env: {name}")
|
|
return value
|
|
|
|
|
|
def build_tat(secret_id: str, secret_key: str, region: str) -> tat_client.TatClient:
|
|
cred = credential.Credential(secret_id, secret_key)
|
|
return tat_client.TatClient(
|
|
cred,
|
|
region,
|
|
ClientProfile(httpProfile=HttpProfile(endpoint="tat.tencentcloudapi.com")),
|
|
)
|
|
|
|
|
|
def remote_script(repo_url: str, repo_ref: str, remote_dir: str, app_port: str) -> str:
|
|
return f"""set -euo pipefail
|
|
|
|
REPO_URL={json.dumps(repo_url)}
|
|
REPO_REF={json.dumps(repo_ref)}
|
|
REMOTE_DIR={json.dumps(remote_dir)}
|
|
APP_PORT={json.dumps(app_port)}
|
|
|
|
export GIT_SSH_COMMAND='ssh -o StrictHostKeyChecking=accept-new'
|
|
|
|
mkdir -p "$(dirname "$REMOTE_DIR")"
|
|
|
|
if [ -d "$REMOTE_DIR/.git" ]; then
|
|
git -C "$REMOTE_DIR" fetch --all --prune
|
|
git -C "$REMOTE_DIR" checkout "$REPO_REF"
|
|
git -C "$REMOTE_DIR" pull --ff-only origin "$REPO_REF"
|
|
else
|
|
rm -rf "$REMOTE_DIR"
|
|
git clone --branch "$REPO_REF" "$REPO_URL" "$REMOTE_DIR"
|
|
fi
|
|
|
|
cd "$REMOTE_DIR"
|
|
chmod +x scripts/*.sh
|
|
APP_PORT="$APP_PORT" bash scripts/restart.sh
|
|
sleep 1
|
|
ss -lntp | grep ":$APP_PORT" || true
|
|
"""
|
|
|
|
|
|
def run_tat_script(client: tat_client.TatClient, instance_id: str, script: str, timeout_seconds: int = 600) -> str:
|
|
req = tat_models.RunCommandRequest()
|
|
req.from_json_string(
|
|
json.dumps(
|
|
{
|
|
"CommandName": "hy-app-monitor-deploy",
|
|
"CommandType": "SHELL",
|
|
"Content": base64.b64encode(script.encode("utf-8")).decode("ascii"),
|
|
"InstanceIds": [instance_id],
|
|
"Timeout": timeout_seconds,
|
|
"WorkingDirectory": "/root",
|
|
}
|
|
)
|
|
)
|
|
resp = json.loads(client.RunCommand(req).to_json_string())
|
|
invocation_id = resp["InvocationId"]
|
|
deadline = time.time() + timeout_seconds + 120
|
|
|
|
while time.time() < deadline:
|
|
time.sleep(3)
|
|
query = tat_models.DescribeInvocationTasksRequest()
|
|
query.from_json_string(
|
|
json.dumps(
|
|
{
|
|
"HideOutput": False,
|
|
"Limit": 20,
|
|
"Filters": [{"Name": "invocation-id", "Values": [invocation_id]}],
|
|
}
|
|
)
|
|
)
|
|
data = json.loads(client.DescribeInvocationTasks(query).to_json_string())
|
|
tasks = data.get("InvocationTaskSet") or []
|
|
if not tasks:
|
|
continue
|
|
task = tasks[0]
|
|
status = task["TaskStatus"]
|
|
if status in {"SUCCESS", "FAILED", "TIMEOUT", "CANCELLED", "START_FAILED"}:
|
|
output = base64.b64decode(task.get("TaskResult", {}).get("Output", "")).decode("utf-8", errors="replace")
|
|
if status != "SUCCESS":
|
|
raise SystemExit(output or f"TAT task failed: {status}")
|
|
return output
|
|
raise SystemExit("TAT task timed out")
|
|
|
|
|
|
def main() -> None:
|
|
secret_id = env_required("TENCENT_SECRET_ID")
|
|
secret_key = env_required("TENCENT_SECRET_KEY")
|
|
instance_id = os.environ.get("DEPLOY_INSTANCE_ID", DEFAULT_INSTANCE_ID)
|
|
region = os.environ.get("DEPLOY_REGION", DEFAULT_REGION)
|
|
repo_url = os.environ.get("MONITOR_REPO_URL", DEFAULT_REPO_URL)
|
|
repo_ref = os.environ.get("MONITOR_REPO_REF", DEFAULT_REPO_REF)
|
|
remote_dir = os.environ.get("MONITOR_REMOTE_DIR", DEFAULT_REMOTE_DIR)
|
|
app_port = os.environ.get("APP_PORT", DEFAULT_APP_PORT)
|
|
|
|
tat = build_tat(secret_id, secret_key, region)
|
|
output = run_tat_script(tat, instance_id, remote_script(repo_url, repo_ref, remote_dir, app_port))
|
|
print(output.strip())
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|