Add backup job controls and systemd status
This commit is contained in:
@@ -12,6 +12,59 @@ from services.backup import backup_badge, restore_help
|
||||
from services.runner import run_cmd
|
||||
|
||||
|
||||
def _parse_systemctl_kv(raw: str) -> dict[str, str]:
|
||||
data: dict[str, str] = {}
|
||||
for line in raw.splitlines():
|
||||
if "=" not in line:
|
||||
continue
|
||||
key, value = line.split("=", 1)
|
||||
data[key.strip()] = value.strip()
|
||||
return data
|
||||
|
||||
|
||||
async def _unit_status(unit: str, props: list[str]) -> dict[str, str]:
|
||||
args = ["systemctl", "show", unit] + [f"-p{prop}" for prop in props]
|
||||
rc, out = await run_cmd(args, timeout=10)
|
||||
if rc != 0:
|
||||
return {"error": out.strip() or f"systemctl {unit} failed"}
|
||||
return _parse_systemctl_kv(out)
|
||||
|
||||
|
||||
async def send_backup_jobs_status(msg: Message):
|
||||
services = [
|
||||
("backup-auto", "backup-auto.timer"),
|
||||
("restic-check", "restic-check.timer"),
|
||||
("weekly-report", "weekly-report.timer"),
|
||||
]
|
||||
service_props = ["ActiveState", "SubState", "Result", "ExecMainStatus", "ExecMainExitTimestamp"]
|
||||
timer_props = ["LastTriggerUSecRealtime", "NextElapseUSecRealtime"]
|
||||
|
||||
lines = ["🕒 Backup jobs\n"]
|
||||
for service, timer in services:
|
||||
svc = await _unit_status(f"{service}.service", service_props)
|
||||
tmr = await _unit_status(timer, timer_props)
|
||||
if "error" in svc:
|
||||
lines.append(f"🔴 {service}: {svc['error']}")
|
||||
continue
|
||||
|
||||
active = svc.get("ActiveState", "n/a")
|
||||
result = svc.get("Result", "n/a")
|
||||
exit_status = svc.get("ExecMainStatus", "n/a")
|
||||
last = svc.get("ExecMainExitTimestamp", "n/a")
|
||||
next_run = tmr.get("NextElapseUSecRealtime", "n/a")
|
||||
last_trigger = tmr.get("LastTriggerUSecRealtime", "n/a")
|
||||
|
||||
lines.append(
|
||||
f"🧊 {service}: {active} ({result}, rc={exit_status})"
|
||||
)
|
||||
lines.append(f" Last run: {last}")
|
||||
lines.append(f" Last trigger: {last_trigger}")
|
||||
lines.append(f" Next: {next_run}")
|
||||
lines.append("")
|
||||
|
||||
await msg.answer("\n".join(lines).rstrip(), reply_markup=backup_kb)
|
||||
|
||||
|
||||
async def cmd_repo_stats(msg: Message):
|
||||
await msg.answer("⏳ Loading repo stats…", reply_markup=backup_kb)
|
||||
|
||||
@@ -104,6 +157,7 @@ async def cmd_backup_status(msg: Message):
|
||||
f"📦 Snapshots ({len(snaps)})\n{badge}",
|
||||
reply_markup=kb
|
||||
)
|
||||
await send_backup_jobs_status(msg)
|
||||
|
||||
asyncio.create_task(worker())
|
||||
|
||||
@@ -202,6 +256,34 @@ async def br(msg: Message):
|
||||
await cmd_backup_now(msg)
|
||||
|
||||
|
||||
@dp.message(F.text == "🧪 Restic check")
|
||||
async def rc(msg: Message):
|
||||
if not is_admin_msg(msg):
|
||||
return
|
||||
|
||||
async def job():
|
||||
await msg.answer("🧪 Restic check запущен", reply_markup=backup_kb)
|
||||
rc2, out = await run_cmd(["sudo", "/usr/local/bin/restic-check.sh"], timeout=6 * 3600)
|
||||
await msg.answer(("✅ OK\n" if rc2 == 0 else "❌ FAIL\n") + out, reply_markup=backup_kb)
|
||||
|
||||
pos = await enqueue("restic-check", job)
|
||||
await msg.answer(f"🕓 Restic check queued (#{pos})", reply_markup=backup_kb)
|
||||
|
||||
|
||||
@dp.message(F.text == "📬 Weekly report")
|
||||
async def wr(msg: Message):
|
||||
if not is_admin_msg(msg):
|
||||
return
|
||||
|
||||
async def job():
|
||||
await msg.answer("📬 Weekly report запущен", reply_markup=backup_kb)
|
||||
rc2, out = await run_cmd(["sudo", "/usr/local/bin/weekly-report.sh"], timeout=3600)
|
||||
await msg.answer(("✅ OK\n" if rc2 == 0 else "❌ FAIL\n") + out, reply_markup=backup_kb)
|
||||
|
||||
pos = await enqueue("weekly-report", job)
|
||||
await msg.answer(f"🕓 Weekly report queued (#{pos})", reply_markup=backup_kb)
|
||||
|
||||
|
||||
@dp.message(F.text == "🧯 Restore help")
|
||||
async def rh(msg: Message):
|
||||
if is_admin_msg(msg):
|
||||
|
||||
@@ -38,7 +38,7 @@ backup_kb = ReplyKeyboardMarkup(
|
||||
[KeyboardButton(text="📦 Status"), KeyboardButton(text="📦 Last snapshot")],
|
||||
[KeyboardButton(text="📊 Repo stats"), KeyboardButton(text="🧯 Restore help")],
|
||||
[KeyboardButton(text="▶️ Run backup"), KeyboardButton(text="🧾 Queue")],
|
||||
[KeyboardButton(text="⬅️ Назад")],
|
||||
[KeyboardButton(text="🧪 Restic check"), KeyboardButton(text="📬 Weekly report"), KeyboardButton(text="⬅️ Назад")],
|
||||
],
|
||||
resize_keyboard=True,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user