ops: add native systemd user deployment
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
[Unit]
|
||||
Description=DobotAI external DingTalk and WeKnora gateway
|
||||
Documentation=file:///home/zheromiku/dobotai-platform/README.md
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=/home/zheromiku/dobotai-platform
|
||||
ExecStart=/usr/bin/python3 /home/zheromiku/dobotai-platform/scripts/run-local.py
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
TimeoutStopSec=20s
|
||||
KillMode=control-group
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
UMask=0077
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
root="/home/zheromiku/dobotai-platform"
|
||||
go_bin="${GO_BIN:-/home/zheromiku/.local/share/go1.26.5/bin/go}"
|
||||
bin_dir="$root/bin"
|
||||
current="$bin_dir/dobotai"
|
||||
next="$bin_dir/dobotai.new"
|
||||
previous="$bin_dir/dobotai.prev"
|
||||
service="dobotai.service"
|
||||
|
||||
mkdir -p "$bin_dir"
|
||||
cd "$root"
|
||||
|
||||
"$go_bin" build -trimpath -o "$next" ./cmd/dobotai
|
||||
chmod 0755 "$next"
|
||||
|
||||
if [[ -f "$current" ]]; then
|
||||
cp -p "$current" "$previous"
|
||||
fi
|
||||
mv -f "$next" "$current"
|
||||
|
||||
systemctl --user restart "$service"
|
||||
|
||||
for _ in $(seq 1 30); do
|
||||
if curl --noproxy '*' --fail --silent --max-time 2 http://127.0.0.1:8090/healthz >/dev/null; then
|
||||
echo "DOBOTAI_DEPLOY_OK"
|
||||
exit 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "DobotAI health check failed; attempting binary rollback" >&2
|
||||
if [[ -f "$previous" ]]; then
|
||||
cp -p "$previous" "$current"
|
||||
systemctl --user restart "$service"
|
||||
fi
|
||||
systemctl --user status "$service" --no-pager >&2 || true
|
||||
exit 1
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Load DobotAI's local .env without shell evaluation, then exec the binary."""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path("/home/zheromiku/dobotai-platform")
|
||||
ENV_FILE = ROOT / ".env"
|
||||
BINARY = ROOT / "bin" / "dobotai"
|
||||
|
||||
|
||||
def load_env(path: Path) -> dict[str, str]:
|
||||
env = os.environ.copy()
|
||||
for raw in path.read_text().splitlines():
|
||||
line = raw.strip()
|
||||
if not line or line.startswith("#") or "=" not in line:
|
||||
continue
|
||||
key, value = line.split("=", 1)
|
||||
env[key.strip()] = value.strip()
|
||||
# WeKnora is local and DingTalk is directly reachable in China. Do not make
|
||||
# the service depend on a desktop proxy that may be absent during boot.
|
||||
for key in (
|
||||
"HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY",
|
||||
"http_proxy", "https_proxy", "all_proxy",
|
||||
):
|
||||
env.pop(key, None)
|
||||
env["NO_PROXY"] = "localhost,127.0.0.1"
|
||||
env["no_proxy"] = env["NO_PROXY"]
|
||||
return env
|
||||
|
||||
|
||||
def main() -> None:
|
||||
if not ENV_FILE.is_file():
|
||||
raise SystemExit(f"missing environment file: {ENV_FILE}")
|
||||
if not BINARY.is_file():
|
||||
raise SystemExit(f"missing DobotAI binary: {BINARY}")
|
||||
os.chdir(ROOT)
|
||||
os.execve(BINARY, [str(BINARY)], load_env(ENV_FILE))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user