Some checks failed
Aurélio Sync & Conscience Upgrade / Upgrade Réplica Conscience (push) Failing after 51s
CI — Test & Build All / aurelio-vscode (push) Failing after 1m31s
CI — Test & Build All / aurelio-backend (push) Failing after 1m16s
CI — Test & Build All / tilth (push) Failing after 1s
CI — Test & Build All / toon (push) Successful in 1m37s
CI — Test & Build All / dirac (push) Failing after 2m35s
CI — Test & Build All / Deploy VSIX to CT 205 (push) Has been skipped
CI — Test & Build All / monorepo (mirrors + unified tests) (push) Failing after 2m4s
Co-authored-by: Álvaro de Campos <campos@portugalfuturista.org>
133 lines
4.1 KiB
Python
133 lines
4.1 KiB
Python
#!/usr/bin/env python3
|
|
"""Aurelio cron scheduler manager for CT 208 systemd timers.
|
|
|
|
Replaces Hermes gateway cron jobs with resilient, always-on systemd timers.
|
|
Subcommands:
|
|
install — copy service/timer units to CT 208 and enable them
|
|
run-now <job> — trigger a job immediately
|
|
status — show all Aurelio timer statuses
|
|
disable <job> — disable a timer
|
|
enable <job> — enable a timer
|
|
|
|
Jobs:
|
|
lifestream-digest — daily roundtable digest of Telegram Saved Messages
|
|
weekly-midi — weekly MuScriptor top-tracks → MIDI pipeline
|
|
"""
|
|
import argparse
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
HOST = "root@192.168.0.38"
|
|
SSH_ID = os.environ.get("AURELIO_SSH_KEY", str(Path.home() / ".ssh" / "id_ed25519_pf"))
|
|
SSH = ["ssh", "-i", SSH_ID, "-o", "ConnectTimeout=10", "-o", "BatchMode=yes", HOST]
|
|
SCP = ["scp", "-i", SSH_ID, "-o", "ConnectTimeout=10", "-o", "BatchMode=yes"]
|
|
UNITS = {
|
|
"lifestream-digest": {
|
|
"service": "aurelio-lifestream-digest.service",
|
|
"timer": "aurelio-lifestream-digest.timer",
|
|
},
|
|
"weekly-midi": {
|
|
"service": "aurelio-weekly-midi.service",
|
|
"timer": "aurelio-weekly-midi.timer",
|
|
},
|
|
}
|
|
|
|
|
|
def run_ssh(cmd: str, check: bool = True) -> subprocess.CompletedProcess:
|
|
return subprocess.run([*SSH, cmd], check=check, text=True, capture_output=True)
|
|
|
|
|
|
def copy_unit(local: Path, unit: str) -> None:
|
|
subprocess.run(
|
|
[*SCP, str(local), f"{HOST}:/etc/systemd/system/{unit}"],
|
|
check=True,
|
|
)
|
|
|
|
|
|
def cmd_install(args) -> int:
|
|
base = Path(__file__).resolve().parent / "systemd"
|
|
if not base.exists():
|
|
print(f"Unit files not found at {base}")
|
|
return 1
|
|
|
|
for name, units in UNITS.items():
|
|
for unit in (units["service"], units["timer"]):
|
|
local = base / unit
|
|
if not local.exists():
|
|
print(f"[skip] missing {local}")
|
|
continue
|
|
copy_unit(local, unit)
|
|
print(f"[install] {unit}")
|
|
|
|
run_ssh("systemctl daemon-reload")
|
|
for name, units in UNITS.items():
|
|
run_ssh(f"systemctl enable --now {units['timer']}")
|
|
print(f"[enable] {units['timer']}")
|
|
return 0
|
|
|
|
|
|
def cmd_run_now(args) -> int:
|
|
units = UNITS.get(args.job)
|
|
if not units:
|
|
print(f"Unknown job: {args.job}. Known: {', '.join(UNITS)}")
|
|
return 1
|
|
run_ssh(f"systemctl start {units['service']}")
|
|
print(f"[trigger] {units['service']}")
|
|
return 0
|
|
|
|
|
|
def cmd_status(args) -> int:
|
|
r = run_ssh("systemctl list-timers --all --no-pager | grep -E 'aurelio-|(NEXT|UNIT|TIMER)'")
|
|
print(r.stdout or r.stderr)
|
|
r = run_ssh("systemctl status 'aurelio-*' --no-pager -n 5 || true", check=False)
|
|
if r.stdout:
|
|
print(r.stdout)
|
|
return 0
|
|
|
|
|
|
def cmd_disable(args) -> int:
|
|
units = UNITS.get(args.job)
|
|
if not units:
|
|
print(f"Unknown job: {args.job}")
|
|
return 1
|
|
run_ssh(f"systemctl disable --now {units['timer']}")
|
|
print(f"[disable] {units['timer']}")
|
|
return 0
|
|
|
|
|
|
def cmd_enable(args) -> int:
|
|
units = UNITS.get(args.job)
|
|
if not units:
|
|
print(f"Unknown job: {args.job}")
|
|
return 1
|
|
run_ssh(f"systemctl enable --now {units['timer']}")
|
|
print(f"[enable] {units['timer']}")
|
|
return 0
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(description="Manage Aurelio cron timers on CT 208")
|
|
sub = parser.add_subparsers(dest="command", required=True)
|
|
sub.add_parser("install", help="Install and enable Aurelio systemd timers")
|
|
sub.add_parser("status", help="Show Aurelio timer status")
|
|
p_run = sub.add_parser("run-now", help="Trigger a job immediately")
|
|
p_run.add_argument("job", choices=list(UNITS))
|
|
p_dis = sub.add_parser("disable", help="Disable a timer")
|
|
p_dis.add_argument("job", choices=list(UNITS))
|
|
p_en = sub.add_parser("enable", help="Enable a timer")
|
|
p_en.add_argument("job", choices=list(UNITS))
|
|
|
|
args = parser.parse_args()
|
|
return {
|
|
"install": cmd_install,
|
|
"status": cmd_status,
|
|
"run-now": cmd_run_now,
|
|
"disable": cmd_disable,
|
|
"enable": cmd_enable,
|
|
}[args.command](args)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|