mirror of
https://github.com/BetterCorp/BetterFrame.git
synced 2026-05-26 16:56:33 +00:00
fix: graceful FK violation on event insert + kiosk stale file cleanup
- Event insert: if source_camera_id FK fails (stale kiosk sending old integer IDs), retry with camera_id=NULL. Event still logs, just without camera association. Stops 500 spam until kiosk updates. - Kiosk cleanup on first healthy boot: remove stale OS update staging files (>24h old) from /var/lib/betterframe/tmp/, and old firmware .prev binaries (>7 days) from /opt/betterframe/kiosk/. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b93e9484ff
commit
515f7088cc
2 changed files with 57 additions and 12 deletions
|
|
@ -306,6 +306,7 @@ fn activate(app: &Application) {
|
|||
firmware::mark_firmware_applied();
|
||||
mark_kiosk_healthy();
|
||||
mark_rauc_slot_good();
|
||||
cleanup_stale_files();
|
||||
first_iter = false;
|
||||
}
|
||||
maybe_apply_os_update(&server, &key, &tx_progress);
|
||||
|
|
@ -496,10 +497,37 @@ fn mark_rauc_slot_good() {
|
|||
.status();
|
||||
}
|
||||
|
||||
fn cleanup_stale_files() {
|
||||
// Stale OS update downloads in staging dir.
|
||||
let staging = std::path::Path::new("/var/lib/betterframe/tmp");
|
||||
if staging.is_dir() {
|
||||
if let Ok(entries) = fs::read_dir(staging) {
|
||||
let cutoff = std::time::SystemTime::now() - Duration::from_secs(24 * 3600);
|
||||
for entry in entries.flatten() {
|
||||
let Ok(meta) = entry.metadata() else { continue };
|
||||
let old = meta.modified().map(|m| m < cutoff).unwrap_or(false);
|
||||
if old {
|
||||
info!("cleanup: removing stale staging file {}", entry.path().display());
|
||||
let _ = fs::remove_file(entry.path());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Old firmware .prev binary (only keep if < 7 days old as rollback safety).
|
||||
let prev = std::path::Path::new("/opt/betterframe/kiosk/betterframe-kiosk.prev");
|
||||
if prev.exists() {
|
||||
let cutoff = std::time::SystemTime::now() - Duration::from_secs(7 * 24 * 3600);
|
||||
if let Ok(meta) = prev.metadata() {
|
||||
if meta.modified().map(|m| m < cutoff).unwrap_or(false) {
|
||||
info!("cleanup: removing old firmware .prev");
|
||||
let _ = fs::remove_file(prev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Ask the server whether a full-OS RAUC bundle is available for this
|
||||
/// kiosk. On hit, download + sha256 + `rauc install` + reboot. On miss or
|
||||
/// error: log + keep running. Gated by BF_ENABLE_OS_OTA=1 (default OFF
|
||||
/// for dev kiosks running a non-A/B image).
|
||||
/// kiosk.
|
||||
fn maybe_apply_os_update(server_url: &str, kiosk_key: &str, tx: &mpsc::Sender<WorkerMsg>) {
|
||||
if std::env::var("BF_ENABLE_OS_OTA").as_deref() != Ok("1") {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -695,7 +695,9 @@ function registerKioskRoutes(
|
|||
}
|
||||
}
|
||||
|
||||
const eventId = await repo.insertEvent({
|
||||
let eventId: string;
|
||||
try {
|
||||
eventId = await repo.insertEvent({
|
||||
source_kiosk_id: kiosk.id,
|
||||
source_camera_id: body.camera_id ?? null,
|
||||
source_type: (body.source_type as any) ?? "system",
|
||||
|
|
@ -704,6 +706,21 @@ function registerKioskRoutes(
|
|||
payload: body.payload ?? {},
|
||||
forwarded_to_nodered: false,
|
||||
});
|
||||
} catch (err: any) {
|
||||
if (err?.code === "23503") {
|
||||
eventId = await repo.insertEvent({
|
||||
source_kiosk_id: kiosk.id,
|
||||
source_camera_id: null,
|
||||
source_type: (body.source_type as any) ?? "system",
|
||||
topic: body.topic,
|
||||
property_op: body.property_op ?? null,
|
||||
payload: body.payload ?? {},
|
||||
forwarded_to_nodered: false,
|
||||
});
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
// Side-effect: persist active layout per display so the admin UI can
|
||||
// surface "currently showing X" without having to query event_log.
|
||||
|
|
|
|||
Loading…
Reference in a new issue