Add upgrade confirm and reboot password

This commit is contained in:
2026-02-07 23:54:39 +03:00
parent bfcd8b4833
commit cd242edaee
3 changed files with 86 additions and 12 deletions

View File

@@ -1,16 +1,15 @@
import asyncio
from aiogram import F
from aiogram.types import Message, CallbackQuery
from app import dp
from aiogram.types import Message, CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton
from app import dp, cfg
from auth import is_admin_msg
from keyboards import system_kb
from system_checks import security, disks
from app import cfg
from services.http_checks import get_url_checks, check_url
import asyncio
from services.queue import enqueue
from services.updates import list_updates, apply_updates
from state import UPDATES_CACHE
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from services.runner import run_cmd
from state import UPDATES_CACHE, REBOOT_PENDING
@dp.message(F.text == "💽 Disks")
@@ -42,7 +41,7 @@ async def urls(msg: Message):
results = await asyncio.gather(*tasks)
lines = ["🌐 URLs\n"]
for (alias, url), (ok, status, ms, err) in zip(checks, results):
for (alias, _url), (ok, status, ms, err) in zip(checks, results):
if ok:
lines.append(f"🟢 {alias}: {status} ({ms}ms)")
elif status is not None:
@@ -79,12 +78,27 @@ async def updates_apply(msg: Message):
if not is_admin_msg(msg):
return
async def job():
text = await apply_updates()
await msg.answer(text, reply_markup=system_kb, parse_mode="Markdown")
kb = InlineKeyboardMarkup(
inline_keyboard=[[
InlineKeyboardButton(text="✅ Confirm", callback_data="upgrade:confirm"),
InlineKeyboardButton(text="✖ Cancel", callback_data="upgrade:cancel"),
]]
)
await msg.answer("⚠️ Confirm package upgrade?", reply_markup=kb)
pos = await enqueue("pkg-upgrade", job)
await msg.answer(f"🕓 Upgrade queued (#{pos})", reply_markup=system_kb)
@dp.message(F.text == "🔄 Reboot")
async def reboot_request(msg: Message):
if not is_admin_msg(msg):
return
kb = InlineKeyboardMarkup(
inline_keyboard=[[
InlineKeyboardButton(text="✅ Confirm", callback_data="reboot:confirm"),
InlineKeyboardButton(text="✖ Cancel", callback_data="reboot:cancel"),
]]
)
await msg.answer("⚠️ Confirm reboot?", reply_markup=kb)
def _updates_kb(page: int, total_pages: int) -> InlineKeyboardMarkup:
@@ -133,3 +147,59 @@ async def updates_page(cb: CallbackQuery):
return
await cb.answer()
await send_updates_page(cb.message, cb.from_user.id, page, edit=True)
@dp.callback_query(F.data == "upgrade:confirm")
async def upgrade_confirm(cb: CallbackQuery):
if cb.from_user.id != cfg["telegram"]["admin_id"]:
return
await cb.answer()
async def job():
text = await apply_updates()
await cb.message.answer(text, reply_markup=system_kb, parse_mode="Markdown")
pos = await enqueue("pkg-upgrade", job)
await cb.message.answer(f"🕓 Upgrade queued (#{pos})", reply_markup=system_kb)
@dp.callback_query(F.data == "upgrade:cancel")
async def upgrade_cancel(cb: CallbackQuery):
await cb.answer("Cancelled")
@dp.callback_query(F.data == "reboot:confirm")
async def reboot_confirm(cb: CallbackQuery):
if cb.from_user.id != cfg["telegram"]["admin_id"]:
return
await cb.answer()
REBOOT_PENDING[cb.from_user.id] = {}
await cb.message.answer("🔐 Send reboot password", reply_markup=system_kb)
@dp.callback_query(F.data == "reboot:cancel")
async def reboot_cancel(cb: CallbackQuery):
await cb.answer("Cancelled")
@dp.message(F.text, F.func(lambda msg: msg.from_user and msg.from_user.id in REBOOT_PENDING))
async def reboot_password(msg: Message):
if not is_admin_msg(msg):
return
REBOOT_PENDING.pop(msg.from_user.id, None)
expected = cfg.get("security", {}).get("reboot_password")
if not expected:
await msg.answer("⚠️ Reboot password not configured", reply_markup=system_kb)
return
if (msg.text or "").strip() != expected:
await msg.answer("❌ Wrong password", reply_markup=system_kb)
return
async def job():
await msg.answer("🔄 Rebooting…", reply_markup=system_kb)
await run_cmd(["sudo", "reboot"], timeout=10)
pos = await enqueue("reboot", job)
await msg.answer(f"🕓 Reboot queued (#{pos})", reply_markup=system_kb)