Watch
1
0
Fork
You've already forked SouveraineOS
0

tasks: updater shipped, edge clobber fixed

This commit is contained in:
Fimeg 2026-07-25 18:41:24 -04:00
commit b7682206be
2 changed files with 86 additions and 16 deletions

View file

@ -37,6 +37,7 @@ Four of them carry a `.gitea/workflows/`. One produces a package.
| repo | runs | green | publishes |
|---|---|---|---|
| `souveraine` | 48 | yes, #4448 | signed pacman repo → `edge` release |
| `souveraine-updater` | 1 | **green on its first run, 07-25** | signed pkg → `edge`, both arches |
| `culver` | 17 | **first green ever: #17, 07-25** | nothing — CI has no packaging step |
| `Pixel3Arch` | 11 | **never** | nothing |
| `linux-blueline`, `pocketboot`, `souveraine-player`, `stevia`, `tuie`, `profile-engine`, … | — | no CI | nothing |
@ -103,12 +104,28 @@ finding 6 happened, and nothing isolates the next one.
present 2026-07-25**; a stale duplicate remains at
`archive/kernel/config-blueline.aarch64` and should go.
3. **The `edge` release clobbers other producers.** `ci.yml` deletes and
recreates the release and tag, uploading only its own `pacman-repo` after
`rm -rf`. Anything another job published there is erased on the next
souveraine push. Casey chose the **additive** shape 2026-07-25: stop
delete-and-recreate, read-modify-write `souveraine-<arch>.db` under a shared
archdev flock, each producer deleting only its own superseded assets.
3. ~~**The `edge` release clobbers other producers.**~~ **Fixed 2026-07-25**,
souveraine `044c373`. `packaging/arch/publish-edge.sh` replaces the
delete-and-recreate: release and tag are never deleted, the live
`souveraine-<arch>.db` (and `.files`) is fetched and merged with `repo-add`
under a shared archdev flock, and only the producer's own superseded builds
are removed — matched by `%NAME%` in the live db, so a producer cannot delete
another's asset.
Two guards, since the failure is otherwise silent: the merged db must retain
every foreign entry (else abort, archive untouched), and the db is read back
over pacman's own download URL and diffed. A db that is published but
unfetchable is a hard failure, **never** a fall-through to building a fresh
one — that fallback was in the first draft and would have reintroduced the
bug on any transient 500.
Databases are fetched by `releases/download/<tag>/<name>`, not the asset-id
API, which returns attachment metadata rather than bytes on some Gitea
versions.
Rehearsed against a throwaway tag before adoption, and since proven live:
`souveraine-updater` published into `edge` on 2026-07-25 and both
`souveraine` and `upower-souveraine` survived in both per-arch databases.
4. **Unowned files are still the standing risk.** 5,624 under
`/usr /etc /opt /boot`. `/var/cache/hyprpm` was one of them, and that is how

View file

@ -1,7 +1,8 @@
# TASK 29 — SouveraineOS Updater: finish it and put it through the pipeline
**Status:** started 2026-07-25, does not build yet. **Size:** one session to
compile and run; a second to package and ship.
**Status:** **shipped 2026-07-25.** Builds, runs, and installs on the phone by
`pacman -Syu` from the `edge` archive. The app itself still needs real work —
see "What it still needs" at the bottom. **Size:** the pipeline half is done.
The Updater is a Rust/Qt rewrite of the GTK/Python `pachub`. New code, new name
— it is not a fork to be maintained against upstream. It is also the first
@ -96,14 +97,66 @@ This is the piece that matters beyond the app. Nothing in `~/Projects` except
loose QML to `/usr/share/pachub/qml`). It needs rewriting for the new name and
the qrc build — the QML install loop is now wrong, since the UI is embedded.
## Acceptance
## What actually broke, 2026-07-25
- `souveraine-updater` builds on archdev for aarch64 and starts on the phone
with a visible window, package list populated.
- Signals fire: an upgrade reports completion rather than hanging on a spinner.
- The package installs by `pacman -Syu` from the archive, owned by pacman, and a
souveraine push does not delete it.
- No file of it is unowned on the device.
Eight compile errors, then one runtime failure. In order:
- `#[qproperty(String, …)]` — as predicted. cxx-qt has no `String` conversion
across the property boundary; all thirteen are `QString` now.
- `apply_filter` was declared on `PackageManagerRust` taking
`Pin<&mut ffi::PackageManager>`, which is not a valid `self` type without the
unstable `arbitrary_self_types`. Moved onto the QObject.
- `rust()` / `rust_mut()` need `use cxx_qt::CxxQtType`.
- `QGuiApplication::exec` wants the pinned app out of the `UniquePtr`.
- **The root still constructed to null after all of that.** `Main.qml`
instantiates `PackageManager {}` but never imported
`com.souveraine.updater`. Loaded by its qrc URL, a file's implicit import is
its *directory* — which resolves sibling `.qml` views but not a
Rust-registered type, which belongs to the module. `on_object_creation_failed`
is what surfaced it; without that hook this is a silent blank window. Culver
imports its own module in every file for the same reason.
- The icon URL resolved to nothing, as predicted. `qrc_resources` with a
`QmlModule` set prefixes each path with the module import path, landing
exactly on the URL `Sidebar.qml` already used, so the QML was left alone. The
svg moved into `updater-ui/` to keep one copy for both qrc and packaging.
CI ends in a **smoke test that loads the QML root offscreen** and fails on any
stderr. A null root builds green — `cargo build` cannot see this class of bug,
which is how it survived from the start.
## Acceptance — met
- Builds on archdev for aarch64; `build-cross.sh` asserts the binary is aarch64
**and** that every `libQt6*` it NEEDs resolves in the sysroot it linked
against (TASK-27 finding 6: a mixed-ABI cross build otherwise looks healthy).
- Runs on the phone: root constructs, 13,278 packages cached, and it lists
itself as `souveraine-updater 0.1.r1.ge4f00c5ffcc9-1` from repo `Souveraine`.
- Installed by pacman from `edge`, signature verified against the archive key.
All four files owned; nothing unowned.
- `pachub` retired — `conflicts`/`replaces` removed it in the same transaction,
taking `/usr/share/pachub` with it.
- A souveraine push can no longer delete it (TASK-27 finding 3, fixed first).
Not verified: the on-screen window. Offscreen proves construction; the visible
check is Casey's, at the device.
## What it still needs
- **Every pacman call is synchronous inside the invokable.** `full_upgrade` and
`rate_mirrors` will freeze the UI for their whole duration. Culver's
`CxxQtThread` + command-channel pattern is the fix.
- **`PackageCache::load()` has no TTL.** `SYNCDB_TTL` (6h) exists but applies
only to `SyncDbCache`, which `load_packages` never calls. So the merged list
is served forever and only `invalidate_all()` clears it — meaning a `pacman`
run *outside* the app leaves the Updater showing stale data indefinitely.
- **QML audit, not yet done.** The whole package set crosses as a JSON string
and is reparsed on every filter keystroke; this wants a real
`QAbstractListModel`. `pm` is passed untyped into the views.
- **The SVG is still `mrks1469`'s artwork, renamed.** GPL-2.0 so redistribution
is fine, but it is not first-party. Replace it.
- `updater-core::auth` shells out to `pkexec`; behaviour with no polkit agent
running is still unverified.
- `cargo test` runs zero tests.
## Connects to