98 lines
2.6 KiB
Python
98 lines
2.6 KiB
Python
#!/usr/bin/env python3
|
|
"""Deploy script for Smart Serow Flutter UI.
|
|
|
|
Pushes build bundle to Pi and optionally restarts service.
|
|
"""
|
|
|
|
import argparse
|
|
import json
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
from pathlib import Path
|
|
|
|
|
|
SCRIPT_DIR = Path(__file__).parent.resolve()
|
|
PROJECT_ROOT = SCRIPT_DIR.parent
|
|
CONFIG_FILE = SCRIPT_DIR / "deploy_target.json"
|
|
BUILD_DIR = PROJECT_ROOT / "pi" / "ui" / "build" / "elinux" / "arm64" / "release" / "bundle"
|
|
|
|
|
|
def run(cmd: list[str], check: bool = True, **kwargs) -> subprocess.CompletedProcess:
|
|
"""Run a command."""
|
|
print(f" → {' '.join(cmd)}")
|
|
return subprocess.run(cmd, check=check, **kwargs)
|
|
|
|
|
|
def load_config() -> dict:
|
|
"""Load deploy target configuration."""
|
|
if not CONFIG_FILE.exists():
|
|
print(f"ERROR: Config file not found: {CONFIG_FILE}")
|
|
print("Create it based on deploy_target.sample.json")
|
|
sys.exit(1)
|
|
|
|
with open(CONFIG_FILE) as f:
|
|
return json.load(f)
|
|
|
|
|
|
def deploy(restart: bool = False) -> bool:
|
|
"""Deploy to Pi. Returns True on success."""
|
|
config = load_config()
|
|
|
|
pi_user = config["user"]
|
|
pi_host = config["host"]
|
|
remote_path = config["remote_path"]
|
|
service_name = config["service_name"]
|
|
|
|
ssh_target = f"{pi_user}@{pi_host}"
|
|
|
|
print("=== Smart Serow Deploy ===")
|
|
print(f"Target: {ssh_target}:{remote_path}")
|
|
print(f"Source: {BUILD_DIR}")
|
|
|
|
if not BUILD_DIR.exists():
|
|
print("ERROR: Build directory not found. Run build.py first.")
|
|
return False
|
|
|
|
# Sync build to Pi
|
|
print()
|
|
print("Syncing files...")
|
|
run([
|
|
"rsync", "-avz", "--delete",
|
|
f"{BUILD_DIR}/",
|
|
f"{ssh_target}:{remote_path}/bundle/",
|
|
])
|
|
|
|
# Restart service if requested
|
|
if restart:
|
|
print()
|
|
print(f"Restarting service: {service_name}")
|
|
run(["ssh", ssh_target, f"sudo systemctl restart {service_name}"])
|
|
time.sleep(2)
|
|
run(["ssh", ssh_target, f"systemctl status {service_name} --no-pager"], check=False)
|
|
else:
|
|
print()
|
|
print("Deploy complete. To restart service, run:")
|
|
print(f" ssh {ssh_target} 'sudo systemctl restart {service_name}'")
|
|
print()
|
|
print("Or run this script with --restart flag")
|
|
|
|
return True
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Deploy Smart Serow to Pi")
|
|
parser.add_argument(
|
|
"--restart", "-r",
|
|
action="store_true",
|
|
help="Restart the systemd service after deploy",
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
success = deploy(restart=args.restart)
|
|
sys.exit(0 if success else 1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|