The root helper, its unit, the group-scoped polkit rule and the install-kind
marker all shipped with the HOST package. A Steam Deck or a handheld has no host
package, so the client half of one-tap updates had nothing to stand on.
The client packages now ship their own copies — deliberately under their own
paths (`pf-update-client`, `punktfunk-client-update.service`,
`49-punktfunk-client-update.rules`, `/usr/share/punktfunk-client/install-kind`)
rather than sharing the host's. Two packages owning one path is a hard conflict
in dpkg, rpm and pacman alike, and the client marker needs its own DIRECTORY
too because the host RPM claims `%{_datadir}/punktfunk/*` with a glob — a
sibling file there would break `dnf install punktfunk punktfunk-client`.
`pf-update` grows the matching `apply-client` verb. The verb comes from a
root-owned unit's fixed ExecStart, never from the caller, so the zero-parameter
invariant holds; both verbs sweep every installed punktfunk package, and what
the verb selects is which marker is read and which binary the run-the-binary
gate executes afterwards. A client sysext is refused with its reason: the signed
feed carries the host image, and installing that over a client-only box is not
an update.
The opt-in group is created by both packages' scriptlets, idempotently, so
whichever lands first wins.
Also fixes the host's own helper install: it read `$R/target/release/pf-update`,
which is the source checkout, while build() exports CARGO_TARGET_DIR="$srcdir/
target" and every other binary in the file installs from `$T`. Both now read
`$T`.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
25 lines
1.2 KiB
Plaintext
25 lines
1.2 KiB
Plaintext
// Members of the `punktfunk-update` group may START exactly one more unit: the punktfunk
|
|
// root-helper oneshot that updates the punktfunk CLIENT packages (planning:
|
|
// host-update-from-web-console.md §7). Sibling of 49-punktfunk-update.rules, which grants the
|
|
// host's unit; the group is the same one, so a box that has opted in has opted in once.
|
|
//
|
|
// The group ships EMPTY — joining it is the explicit, auditable opt-in for one-tap client
|
|
// updates (the Decky plugin's "Update client" button, `punktfunk-client --apply-update`):
|
|
//
|
|
// sudo usermod -aG punktfunk-update <your user>
|
|
//
|
|
// Scope notes: `verb == "start"` keeps stop/restart/enable out of the grant, and the unit
|
|
// name pin keeps every other unit out. The unit's ExecStart is fixed and parameterless, so
|
|
// this grant authorizes "run the system's normal update for the punktfunk packages" and
|
|
// nothing else.
|
|
polkit.addRule(function (action, subject) {
|
|
if (
|
|
action.id == "org.freedesktop.systemd1.manage-units" &&
|
|
action.lookup("unit") == "punktfunk-client-update.service" &&
|
|
action.lookup("verb") == "start" &&
|
|
subject.isInGroup("punktfunk-update")
|
|
) {
|
|
return polkit.Result.YES;
|
|
}
|
|
});
|