layer-wizard/lib/main.dart
Philip Peterson b935ab01b2 Track our own layer history in a local SQLite DB
rpm-ostree/ostree only retain a couple of deployments, so there's no
durable record of what's been layered since the stock image. Add a
local history DB (lib/history/) keyed on the ostree deployment
checksum, with a parent pointer forming a tree, plus named "current"
and "last_known_safe" pointers.

Reconciling against live `rpm-ostree status --json` on every launch
means the history stays correct even across manual rpm-ostree/bootc
changes made outside this app: any booted checksum we don't recognize
gets recorded as a "detected" node rather than silently ignored.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-06 10:30:59 -08:00

55 lines
1.6 KiB
Dart

import 'package:flutter/material.dart';
import 'confirmation_marker.dart';
import 'confirmation_page.dart';
import 'history/history_service.dart';
import 'wizard_page.dart';
void main() {
runApp(const LayerWizardApp());
}
class LayerWizardApp extends StatelessWidget {
const LayerWizardApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Layer Wizard',
theme: ThemeData(colorSchemeSeed: Colors.teal, useMaterial3: true),
home: const _StartupRouter(),
);
}
}
/// Checks for a pending post-reboot confirmation before deciding which
/// screen to show first.
class _StartupRouter extends StatelessWidget {
const _StartupRouter();
/// Reconciles our layer history against the live `rpm-ostree status`
/// before anything else — catches rollbacks, reboots into our own
/// installs, and any manual changes made outside the app — then checks
/// for a pending post-reboot confirmation.
Future<PendingConfirmation?> _startup() async {
await HistoryService.instance.reconcile();
return ConfirmationMarker.read();
}
@override
Widget build(BuildContext context) {
return FutureBuilder<PendingConfirmation?>(
future: _startup(),
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return const Scaffold(body: Center(child: CircularProgressIndicator()));
}
final pending = snapshot.data;
if (pending != null) {
return ConfirmationPage(pending: pending);
}
return const WizardHomePage();
},
);
}
}