Document the app, and specifically how the post-reboot check works
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
e0cbf8ae20
commit
68ea482240
1 changed files with 84 additions and 11 deletions
95
README.md
95
README.md
|
|
@ -1,17 +1,90 @@
|
|||
# layer_wizard
|
||||
# Layer Wizard
|
||||
|
||||
A new Flutter project.
|
||||
A GUI installer wizard for permanently layering an RPM package onto a
|
||||
bootc/image-based (read-only root) Linux system via `rpm-ostree install`,
|
||||
with a guided reboot step and a one-click rollback if the result looks wrong.
|
||||
|
||||
## Getting Started
|
||||
Built for Universal Blue / Fedora bootc systems, where plain `dnf install`
|
||||
refuses to run (the root filesystem is read-only) and the persistent
|
||||
mechanism is `rpm-ostree install <pkg>`, which stages a new deployment that
|
||||
only takes effect after a reboot.
|
||||
|
||||
This project is a starting point for a Flutter application.
|
||||
## What it does
|
||||
|
||||
A few resources to get you started if this is your first Flutter project:
|
||||
1. **Welcome** — shows the currently booted version/image.
|
||||
2. **Package** — enter a package name; "Check" confirms it resolves
|
||||
(`dnf repoquery`) before anything privileged happens.
|
||||
3. **Confirm** — review the package and what's about to happen.
|
||||
4. **Apply** — runs `pkexec rpm-ostree install -y <package>`, with the
|
||||
PolicyKit password prompt and a live streamed log. On success, offers
|
||||
**Reboot Now** / **Reboot Later**.
|
||||
5. After rebooting, the app **launches itself automatically** and asks:
|
||||
"Is everything working correctly?" — **Yes, keep this update**, or
|
||||
**No, something's wrong — roll back**, which runs
|
||||
`pkexec bootc rollback --apply` (reboots immediately into the previous
|
||||
deployment).
|
||||
|
||||
- [Learn Flutter](https://docs.flutter.dev/get-started/learn-flutter)
|
||||
- [Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
||||
- [Flutter learning resources](https://docs.flutter.dev/reference/learning-resources)
|
||||
## How the post-reboot check works
|
||||
|
||||
For help getting started with Flutter development, view the
|
||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
||||
samples, guidance on mobile development, and a full API reference.
|
||||
This system has no `greenboot` and no automated bad-boot detection
|
||||
(`systemd-bless-boot.service` exists but isn't wired up to anything here) —
|
||||
so the rollback offer is **self-reported**, not automatic. Two pieces make
|
||||
that work:
|
||||
|
||||
- **Autostart entry.** Right after a successful install,
|
||||
`ConfirmationMarker.installAutostart()` (`lib/confirmation_marker.dart`)
|
||||
writes `~/.config/autostart/com.ironmagma.layer_wizard.desktop`, with
|
||||
`Exec=` pointing at the currently-running binary
|
||||
(`Platform.resolvedExecutable`). KDE's session runs everything in
|
||||
`~/.config/autostart/` on login, which is what makes the app reappear on
|
||||
its own right after the reboot — you don't have to remember to open it.
|
||||
|
||||
- **The check itself runs on every launch, not just via autostart.**
|
||||
`lib/main.dart`'s `_StartupRouter` calls `ConfirmationMarker.read()` before
|
||||
deciding what to show:
|
||||
|
||||
```dart
|
||||
future: ConfirmationMarker.read(),
|
||||
builder: (context, snapshot) {
|
||||
final pending = snapshot.data;
|
||||
if (pending != null) return ConfirmationPage(pending: pending);
|
||||
return const WizardHomePage();
|
||||
}
|
||||
```
|
||||
|
||||
`read()` just checks whether
|
||||
`~/.local/state/layer_wizard/pending_confirmation.json` exists and parses
|
||||
it. That file is written by the wizard right after a successful install
|
||||
(`ConfirmationMarker.write(...)` in `lib/wizard_page.dart`), and deleted —
|
||||
along with the autostart entry — as soon as you click **Keep** or
|
||||
**Roll back** in `lib/confirmation_page.dart`.
|
||||
|
||||
Running the check unconditionally at startup (rather than only when
|
||||
launched via autostart) is deliberate: if autostart doesn't fire for some
|
||||
reason, or you dismiss it and reopen the app later, you still land on the
|
||||
confirmation screen instead of that pending state getting silently
|
||||
dropped.
|
||||
|
||||
## Project layout
|
||||
|
||||
- `lib/ostree_service.dart` — all privileged/unprivileged shelling out:
|
||||
`rpm-ostree status --json`, `dnf repoquery`, `pkexec rpm-ostree install`,
|
||||
`pkexec bootc rollback --apply`, `pkexec systemctl reboot`.
|
||||
- `lib/confirmation_marker.dart` — the pending-confirmation marker file and
|
||||
autostart `.desktop` entry (write/read/clear, install/remove).
|
||||
- `lib/wizard_page.dart` — the install wizard (`Stepper`-based).
|
||||
- `lib/confirmation_page.dart` — the post-reboot "did this work?" screen.
|
||||
- `lib/main.dart` — startup routing between the two.
|
||||
|
||||
Privilege escalation follows the same pattern as the sibling
|
||||
[`dnf-package-store`](https://github.com/quine-global-labs/dnf-package-store)
|
||||
app: `pkexec` through the desktop PolicyKit agent, with stdout/stderr
|
||||
streamed line-by-line into the UI.
|
||||
|
||||
## Building
|
||||
|
||||
```
|
||||
flutter build linux
|
||||
```
|
||||
|
||||
Produces `build/linux/x64/release/bundle/layer_wizard`.
|
||||
|
|
|
|||
Loading…
Reference in a new issue