#!/usr/bin/env python3 from __future__ import annotations import argparse import os from pathlib import Path from common import ( DeployError, log, render_template, require_commands, run, sudo_write_text_atomic, ) from deployment_runtime_state import update_env_file def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser() parser.add_argument("--downstream-root") parser.add_argument("--run-now", action="store_true") return parser.parse_args() def deployment_root() -> Path: raw = os.environ.get("DEPLOYMENT_ROOT") if raw: return Path(raw).expanduser().resolve() return (Path.home() / "nexuscrm-deployment").resolve() def offline_envs_root() -> Path: raw = os.environ.get("OFFLINE_ENVS_ROOT") if raw: return Path(raw).expanduser().resolve() return deployment_root() / "offline" / "envs" def default_downstream_root() -> Path: return offline_envs_root() / "staging" / "blue" / "repos" / "nexuscrm-pingcap-pack" def guard_env_file() -> Path: return offline_envs_root() / "staging" / "guard.env" def materialize_guard_env() -> Path: path = guard_env_file() updates = { key: value for key in [ "FEISHU_APP_ID", "FEISHU_APP_SECRET", "FEISHU_CHAT_ID", "FEISHU_GUARD_STAGING_HEADER_TEMPLATE", "FEISHU_GUARD_DEFAULT_HEADER_TEMPLATE", "STAGING_PUBLIC_URL", "STAGING_HEALTHCHECK_HOST", "STAGING_GUARD_HINT", ] if (value := os.environ.get(key, "").strip()) } if updates: update_env_file(path, updates) return path def install_guard_units(framework_dir: Path, downstream_root: Path) -> None: systemd_user = os.environ.get("USER", "ec2-user") replacements = { "__SYSTEMD_USER__": systemd_user, "__DOWNSTREAM_ROOT__": str(downstream_root), "__DEPLOYMENT_ROOT__": str(deployment_root()), } unit_specs = [ ( framework_dir / "systemd/nexuscrm-staging-guard.service.template", Path("/etc/systemd/system/nexuscrm-staging-guard.service"), ), ( framework_dir / "systemd/nexuscrm-staging-guard.timer.template", Path("/etc/systemd/system/nexuscrm-staging-guard.timer"), ), ( framework_dir / "systemd/nexuscrm-offline-host-guard.service.template", Path("/etc/systemd/system/nexuscrm-offline-host-guard.service"), ), ( framework_dir / "systemd/nexuscrm-offline-host-guard.timer.template", Path("/etc/systemd/system/nexuscrm-offline-host-guard.timer"), ), ] for template_path, target_path in unit_specs: rendered = render_template(template_path, replacements) sudo_write_text_atomic(target_path, rendered) run(["sudo", "systemctl", "daemon-reload"]) run(["sudo", "systemctl", "enable", "--now", "nexuscrm-staging-guard.timer"]) run(["sudo", "systemctl", "enable", "--now", "nexuscrm-offline-host-guard.timer"]) def run_guards_now() -> None: run(["sudo", "systemctl", "start", "nexuscrm-staging-guard.service"]) run(["sudo", "systemctl", "status", "--no-pager", "nexuscrm-staging-guard.service"]) run(["sudo", "systemctl", "start", "nexuscrm-offline-host-guard.service"]) run(["sudo", "systemctl", "status", "--no-pager", "nexuscrm-offline-host-guard.service"]) def main() -> int: args = parse_args() try: require_commands("systemctl") framework_dir = Path(__file__).resolve().parents[1] downstream_root = Path(args.downstream_root).expanduser().resolve() if args.downstream_root else default_downstream_root() if not downstream_root.is_dir(): raise DeployError(f"downstream root not found: {downstream_root}") env_path = materialize_guard_env() install_guard_units(framework_dir, downstream_root) if args.run_now: run_guards_now() log(f"offline guard env refreshed: {env_path}") log(f"offline guard repo root: {downstream_root}") return 0 except DeployError as exc: log(f"failed: {exc}") return 1 if __name__ == "__main__": raise SystemExit(main())