Compare commits

..
6 changed files with 26 additions and 72 deletions

View file

@ -1,9 +1,8 @@
name: image name: image
# Builds the flashable postmarketOS images for the Fairphone 6 (kernel from # Builds a flashable postmarketOS image for the Fairphone 6 (kernel from
# milos-linux combined-stable + imsd) — Plasma Mobile (fp6-img.tar.xz) and # milos-linux combined-stable + imsd) and publishes it as the rolling
# Phosh (fp6-img-phosh.tar.xz) — and publishes both as the rolling 'latest' # 'latest' release.
# release.
# #
# Runs on the dedicated privileged runner label "pmos" (loop devices for # Runs on the dedicated privileged runner label "pmos" (loop devices for
# pmbootstrap install, qemu-user binfmt on the host for the aarch64 chroots). # pmbootstrap install, qemu-user binfmt on the host for the aarch64 chroots).
@ -35,16 +34,9 @@ jobs:
with: with:
persist-credentials: true persist-credentials: true
- name: Build image (Plasma Mobile) - name: Build image
run: ./build.sh run: ./build.sh
# Second UI from the same package builds (the kernel and the aports
# above are already current in pmbootstrap's work dir, so this is the
# install + export only): fp6-img-phosh.tar.xz next to fp6-img.tar.xz
# in the same release.
- name: Build image (Phosh)
run: FP6IMG_UI=phosh FP6IMG_KEEP_DIST=1 ./build.sh
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:

View file

@ -31,11 +31,6 @@ cd fp6-img
./install.sh ./install.sh
``` ```
Two images are published per release, same kernel and packages, different
shell: `fp6-img.tar.xz` boots **Plasma Mobile** (calls through Plasma
Dialer), `fp6-img-phosh.tar.xz` boots **Phosh** (calls through GNOME Calls,
via imsd's `imsd-ofono` backend). Pick one; the install steps are identical.
`install.sh` erases dtbo, flashes the rootfs, **RAM-boots** the kernel, writes the boot partition from `install.sh` erases dtbo, flashes the rootfs, **RAM-boots** the kernel, writes the boot partition from
inside Linux where the bootloader's NV-wipe cannot see it, then reads the modem inside Linux where the bootloader's NV-wipe cannot see it, then reads the modem
NV back and reports the result. The bootloader never writes `boot`. NV back and reports the result. The bootloader never writes `boot`.

View file

@ -3,27 +3,22 @@
# Earpiece port), leaving plasma-dialer's mute button dead and blocking # Earpiece port), leaving plasma-dialer's mute button dead and blocking
# kde-telephony-daemon 25s per call; see the script header for the full # kde-telephony-daemon 25s per call; see the script header for the full
# write-up. The callaudiod package stays installed (plasma-mobile depends on # write-up. The callaudiod package stays installed (plasma-mobile depends on
# it); this package replaces its D-Bus activation file, so activating # it) — this shim simply owns org.mobian_project.CallAudio first via an
# org.mobian_project.CallAudio starts the shim in any session. Phosh # early-phase autostart, so D-Bus activation of the real daemon never fires.
# activates the name at startup, before autostart runs, and the stock daemon # Deployed and tested on the development FP6.
# used to win there (1-r0). Removing this package removes the activation file
# too; 'apk fix callaudiod' restores callaudiod's. Deployed and tested on the
# development FP6.
maintainer="Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>" maintainer="Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>"
pkgname=callaudioshim pkgname=callaudioshim
pkgver=1 pkgver=1
pkgrel=1 pkgrel=0
pkgdesc="callaudiod replacement shim: working in-call mic mute on the FP6" pkgdesc="callaudiod replacement shim: working in-call mic mute on the FP6"
url="https://forgejo.catcrafts.net/Catcrafts/fp6-img" url="https://forgejo.catcrafts.net/Catcrafts/fp6-img"
arch="noarch" arch="noarch"
license="GPL-3.0-only" license="GPL-3.0-only"
depends="python3 py3-dbus py3-gobject3 wireplumber" depends="python3 py3-dbus py3-gobject3 wireplumber"
replaces="callaudiod"
options="!check" options="!check"
source=" source="
callaudioshim.py callaudioshim.py
callaudioshim.desktop callaudioshim.desktop
org.mobian_project.CallAudio.service
" "
package() { package() {
@ -31,12 +26,9 @@ package() {
"$pkgdir"/usr/libexec/callaudioshim.py "$pkgdir"/usr/libexec/callaudioshim.py
install -Dm644 "$srcdir"/callaudioshim.desktop \ install -Dm644 "$srcdir"/callaudioshim.desktop \
"$pkgdir"/etc/xdg/autostart/callaudioshim.desktop "$pkgdir"/etc/xdg/autostart/callaudioshim.desktop
install -Dm644 "$srcdir"/org.mobian_project.CallAudio.service \
"$pkgdir"/usr/share/dbus-1/services/org.mobian_project.CallAudio.service
} }
sha512sums=" sha512sums="
05995f0f732319559ccd9a7f3891c6363261e52ddbdf13b812fce580dbb816c362bd76da36cb9f1c7ee203d5ce2486762ffe46a7660dd4bc10c8bf2b4cd1a8ca callaudioshim.py 7ca7d75402ea6c48a7c1c19c5c5ed6e556f2c0133aa6e32a12f5c5a1afc0c791f04ebd40102a4b92b0dd87f9330ae64ada025c344525b9ed17289acd8cb952d7 callaudioshim.py
060b76660398115af26463425db5a6a2d634b6bdbf48a8ae488528403f8e086a9ef23470316196e6ccd8cb65e0ebd09bbc0df2ff5f8a830407d98404f439c706 callaudioshim.desktop 060b76660398115af26463425db5a6a2d634b6bdbf48a8ae488528403f8e086a9ef23470316196e6ccd8cb65e0ebd09bbc0df2ff5f8a830407d98404f439c706 callaudioshim.desktop
6b44134e3f3ed0a8c3314b0b0cf9a9e5483850cdfb54f486d23199dd9f5f1ee66d674a391126e803796db69182f980b30a714457a81c9a447e146bc9ba5992bd org.mobian_project.CallAudio.service
" "

View file

@ -37,11 +37,9 @@ interface (verified against callaudiod's org.mobian_project.CallAudio.xml):
dynamic in this setup — journal/audio.md 2026-07-18). SpeakerState dynamic in this setup — journal/audio.md 2026-07-18). SpeakerState
defaults to ON. When an Earpiece UCM device exists these become real. defaults to ON. When an Earpiece UCM device exists these become real.
Stock callaudiod must not own the name. The package replaces callaudiod's Stock callaudiod must not own the name: pkill it and mask its D-Bus
D-Bus activation file with one that starts this shim, so whichever client asks activation (see journal/ims.md s44 deploy notes). Runs as the session user
first — Phosh activates the name at startup, before autostart runs — gets the (autostart .desktop), no root needed.
shim; the KDE early-phase autostart stays for the DialerUtils push at session
start. Runs as the session user, no root needed.
""" """
import subprocess import subprocess
@ -187,12 +185,7 @@ class CallAudio(dbus.service.Object):
def main(): def main():
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
session = dbus.SessionBus() session = dbus.SessionBus()
try:
name = dbus.service.BusName(BUS_NAME, session, do_not_queue=True) # noqa: F841 name = dbus.service.BusName(BUS_NAME, session, do_not_queue=True) # noqa: F841
except dbus.exceptions.NameExistsException:
# activated and autostarted in the same session: the first one serves
log(f"callaudioshim: {BUS_NAME} already owned; exiting")
return
CallAudio(session) CallAudio(session)
log(f"callaudioshim: owning {BUS_NAME}") log(f"callaudioshim: owning {BUS_NAME}")
GLib.MainLoop().run() GLib.MainLoop().run()

View file

@ -1,3 +0,0 @@
[D-BUS Service]
Name=org.mobian_project.CallAudio
Exec=/usr/libexec/callaudioshim.py

View file

@ -30,18 +30,6 @@ KERNEL_BRANCH=combined-stable
# sha256; that gated fresh installs only, never upgrades, and cost a commit # sha256; that gated fresh installs only, never upgrades, and cost a commit
# and an image run per release. # and an image run per release.
REGISTRY=https://forgejo.catcrafts.net/api/packages/Catcrafts/alpine/edge/fp6 REGISTRY=https://forgejo.catcrafts.net/api/packages/Catcrafts/alpine/edge/fp6
# FP6IMG_UI: which postmarketOS UI the image boots into. plasma-mobile (the
# default) gets imsd-dialerd from the imsd package itself; phosh gets the
# opt-in imsd-ofono subpackage (imsd-ofonod + the GNOME Calls plugin
# override) on top. Everything else in the package set is UI-agnostic. The
# archive is named after it: fp6-img.tar.xz for plasma-mobile,
# fp6-img-<ui>.tar.xz otherwise, so one release can carry both.
FP6IMG_UI=${FP6IMG_UI:-plasma-mobile}
case "$FP6IMG_UI" in
plasma-mobile) UI_PACKAGES=; IMG_NAME=fp6-img ;;
phosh) UI_PACKAGES=,imsd-ofono; IMG_NAME=fp6-img-phosh ;;
*) echo "FP6IMG_UI=$FP6IMG_UI: expected plasma-mobile or phosh" >&2; exit 1 ;;
esac
PMAPORTS_REPO=https://gitlab.postmarketos.org/postmarketOS/pmaports.git PMAPORTS_REPO=https://gitlab.postmarketos.org/postmarketOS/pmaports.git
cd "$(dirname "$0")" cd "$(dirname "$0")"
@ -95,13 +83,11 @@ if [ "$(id -u)" = 0 ]; then
id build >/dev/null 2>&1 || adduser -D build id build >/dev/null 2>&1 || adduser -D build
echo 'build ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/build echo 'build ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/build
# empty dist in place (never delete the dir itself: a shell cd'd into it # empty dist in place (never delete the dir itself: a shell cd'd into it
# would poison the next podman invocation's cwd). FP6IMG_KEEP_DIST=1 keeps # would poison the next podman invocation's cwd)
# what is there: the second UI build of one run adds its archive next to
# the first one's.
install -d -o build dist install -d -o build dist
[ -n "${FP6IMG_KEEP_DIST:-}" ] || find dist -mindepth 1 -delete find dist -mindepth 1 -delete
# su scrubs the environment — carry the knobs that matter across it # su scrubs the environment — carry the knobs that matter across it
exec su build -c "FP6IMG_NO_CROSSDIRECT='${FP6IMG_NO_CROSSDIRECT:-}' FP6IMG_UI='${FP6IMG_UI:-}' sh -eu '$PWD/build.sh'" exec su build -c "FP6IMG_NO_CROSSDIRECT='${FP6IMG_NO_CROSSDIRECT:-}' sh -eu '$PWD/build.sh'"
fi fi
# git hosts occasionally hiccup (our forgejo lives on a small VM that also # git hosts occasionally hiccup (our forgejo lives on a small VM that also
@ -232,9 +218,9 @@ cat > "$HOME/.config/pmbootstrap_v3.cfg" <<EOF
[pmbootstrap] [pmbootstrap]
aports = $WORK/pmaports aports = $WORK/pmaports
device = fairphone-fp6 device = fairphone-fp6
ui = $FP6IMG_UI ui = plasma-mobile
systemd = always systemd = always
extra_packages = soc-fairphone-fp6-audio,callaudioshim,imsd,fingerprintd,fingerprintd-systemd,fingerprintd-agent,fp6-device-tweaks,fp6-charging-mode,catcrafts-fp6-repo,postmarketos-base-ui-audio-backend-pipewire,pipewire-pulse,pipewire-echo-cancel$UI_PACKAGES extra_packages = soc-fairphone-fp6-audio,callaudioshim,imsd,fingerprintd,fingerprintd-systemd,fingerprintd-agent,fp6-device-tweaks,fp6-charging-mode,catcrafts-fp6-repo,postmarketos-base-ui-audio-backend-pipewire,pipewire-pulse,pipewire-echo-cancel
EOF EOF
# All four source tarballs are generated locally above, so every checksum # All four source tarballs are generated locally above, so every checksum
@ -287,7 +273,7 @@ if [ ! -f "$REGISTRY_KEY" ]; then
exit 1 exit 1
fi fi
retry "fetch registry packages" python3 ./registry-fetch.py "$REGISTRY" "$REGISTRY_KEY" "$REG_DL" \ retry "fetch registry packages" python3 ./registry-fetch.py "$REGISTRY" "$REGISTRY_KEY" "$REG_DL" \
imsd,imsd-systemd,imsd-ofono fingerprintd,fingerprintd-systemd,fingerprintd-agent imsd,imsd-systemd fingerprintd,fingerprintd-systemd,fingerprintd-agent
ABUILD_KEY=$(echo "$WORKDIR"/config_abuild/*.rsa) ABUILD_KEY=$(echo "$WORKDIR"/config_abuild/*.rsa)
if [ ! -f "$ABUILD_KEY" ]; then if [ ! -f "$ABUILD_KEY" ]; then
echo "expected exactly one abuild key in $WORKDIR/config_abuild" >&2 echo "expected exactly one abuild key in $WORKDIR/config_abuild" >&2
@ -339,22 +325,21 @@ pmbootstrap export "$EXPORT"
# so the archive is built without a second 3 GiB copy on disk. # so the archive is built without a second 3 GiB copy on disk.
STAGE="$WORK/stage" STAGE="$WORK/stage"
rm -rf "$STAGE" rm -rf "$STAGE"
mkdir -p "$STAGE/$IMG_NAME" mkdir -p "$STAGE/fp6-img"
ln -s "$EXPORT/boot.img" "$STAGE/$IMG_NAME/boot.img" ln -s "$EXPORT/boot.img" "$STAGE/fp6-img/boot.img"
ln -s "$EXPORT/fairphone-fp6.img" "$STAGE/$IMG_NAME/fairphone-fp6.img" ln -s "$EXPORT/fairphone-fp6.img" "$STAGE/fp6-img/fairphone-fp6.img"
cp README.md install.sh "$STAGE/$IMG_NAME/" cp README.md install.sh "$STAGE/fp6-img/"
{ {
echo "kernel: $KERNEL_REPO $KERNEL_BRANCH @ $COMMIT" echo "kernel: $KERNEL_REPO $KERNEL_BRANCH @ $COMMIT"
echo "ui: $FP6IMG_UI"
echo "built: $(date -u +%Y-%m-%dT%H:%M:%SZ)" echo "built: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "default login: user / 147147 (same as official postmarketOS images)" echo "default login: user / 147147 (same as official postmarketOS images)"
while read -r _n _v _s; do while read -r _n _v _s; do
printf '%-14s %s %s-%s (newest registry package, sha256 %s)\n' "$_n:" "$REGISTRY" "$_n" "$_v" "$_s" printf '%-14s %s %s-%s (newest registry package, sha256 %s)\n' "$_n:" "$REGISTRY" "$_n" "$_v" "$_s"
done < "$REG_DL/manifest" done < "$REG_DL/manifest"
} > "$STAGE/$IMG_NAME/build-info.txt" } > "$STAGE/fp6-img/build-info.txt"
# sums of the extracted contents # sums of the extracted contents
(cd "$STAGE/$IMG_NAME" && sha256sum -- * > sha256sums.txt) (cd "$STAGE/fp6-img" && sha256sum -- * > sha256sums.txt)
tar -C "$STAGE" -chf - "$IMG_NAME" | xz -T0 -6 > "dist/$IMG_NAME.tar.xz" tar -C "$STAGE" -chf - fp6-img | xz -T0 -6 > dist/fp6-img.tar.xz
rm -rf "$STAGE" rm -rf "$STAGE"
ls -la dist/ ls -la dist/