From 347c106498d724af3a34050ac8e602ce2c4ca921 Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Mon, 27 Jul 2026 20:49:46 +0200 Subject: [PATCH] fix(packaging/tray): the .deb must build the tray in its own cargo invocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit punktfunk-tray panicked at every launch on Debian/Ubuntu: zbus-5.16.0/src/abstractions/executor.rs:190 there is no reactor running, must be called from the context of a Tokio 1.x runtime Not a code bug — cargo feature unification. zbus picks its executor from its own feature flags; the host's ashpd enables zbus/tokio while the tray runs ksni's async-io executor with no tokio runtime by design. Features are additive across everything built in ONE invocation, and deb.yml built `-p punktfunk-host -p punktfunk-tray` together, handing the tray a tokio-flavoured zbus with no runtime anywhere near it. The invariant is already established and explained inline in the RPM spec, the Arch PKGBUILD and the Nix packages.nix — all three build the tray alone, and their comments even claim "(Same split the .deb does.)" The .deb did not, in two places at once: the workflow co-built it, and build-deb.sh's own correct standalone build was skipped by an `if [ ! -x "$TRAY_BIN" ]` guard, so it packaged the poisoned artifact. That is also why only Debian/Ubuntu users saw it. Drops the tray from the workflow's host build and makes build-deb.sh's tray build unconditional — cargo no-ops when the artifact is already async-io-resolved and rebuilds it when it is not, so a stale co-built binary can no longer be shipped. Corrects the Nix README note that had recorded deb/rpm/arch as sharing a "latent" crash, and its nix develop recipe, which co-built all four. Verified on a Linux box: co-built reproduces the panic exactly; built alone, the tray reaches the session bus and exits with the intended "no StatusNotifier tray available". Co-Authored-By: Claude Opus 5 (1M context) (cherry picked from commit f91983a84c56464bd2c18d537963cb7fb3a6e059) --- .gitea/workflows/deb.yml | 15 +++++++++++---- packaging/debian/build-deb.sh | 14 ++++++++++---- packaging/nix/README.md | 15 ++++++++++++--- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/.gitea/workflows/deb.yml b/.gitea/workflows/deb.yml index d131dfa6..44456a6c 100644 --- a/.gitea/workflows/deb.yml +++ b/.gitea/workflows/deb.yml @@ -234,11 +234,18 @@ jobs: git config --global --add safe.directory "$PWD" # Same features the old combined build used: --nvenc (direct-SDK NVENC, real RFI on NVIDIA; # NVENC/CUDA is dlopen'd — no link dep, so this image needs no libcuda stub) + --vulkan-encode - # (raw VK_KHR_video_encode_h265 on AMD/Intel, pure ash). punktfunk-tray also ships in the host - # .deb (build-deb.sh builds+installs it). ffmpeg-sys-next links the image's bundled FFmpeg 8 - # via PKG_CONFIG_PATH (set in rust-ci-noble). + # (raw VK_KHR_video_encode_h265 on AMD/Intel, pure ash). ffmpeg-sys-next links the image's + # bundled FFmpeg 8 via PKG_CONFIG_PATH (set in rust-ci-noble). + # + # punktfunk-tray is deliberately NOT in this invocation — build-deb.sh builds it separately, + # and that split is load-bearing (see the identical note in the RPM spec / Arch PKGBUILD): + # cargo unifies features across one build, so co-building the tray with the host pulls the + # host's ashpd -> zbus/tokio onto the tray's shared zbus and the tray panics at every launch + # with "there is no reactor running, must be called from the context of a Tokio 1.x runtime". + # It WAS listed here, which is why only the .deb shipped a crashing tray while the RPM and + # Arch packages — which already split it — were fine. cargo build --release --locked --features punktfunk-host/nvenc,punktfunk-host/vulkan-encode \ - -p punktfunk-host -p punktfunk-tray + -p punktfunk-host - name: Build host .deb (FFmpeg bundled) # BUNDLE_FFMPEG=1 copies the image's /opt/ffmpeg libav* into the package and repoints the diff --git a/packaging/debian/build-deb.sh b/packaging/debian/build-deb.sh index 865fb65b..64dd6c00 100755 --- a/packaging/debian/build-deb.sh +++ b/packaging/debian/build-deb.sh @@ -39,10 +39,16 @@ if [ ! -x "$BIN" ]; then PUNKTFUNK_BUILD_VERSION="$VERSION" cargo build --release -p "$PKG" --locked # stamp --version (build.rs) fi TRAY_BIN="target/release/punktfunk-tray" -if [ ! -x "$TRAY_BIN" ]; then - echo "==> building punktfunk-tray (release)" - cargo build --release -p punktfunk-tray --locked -fi +# ALWAYS built here, in its OWN cargo invocation — load-bearing, not tidiness, and deliberately not +# skipped when the artifact already exists. Cargo unifies features across everything in one build, +# so a caller that co-built the tray with the host (the .deb workflow used to) leaves behind a +# binary whose zbus took the host's ashpd -> zbus/tokio while the tray runs ksni's async-io +# executor with no tokio runtime by design — it then panics at every launch with "there is no +# reactor running, must be called from the context of a Tokio 1.x runtime". Skipping the rebuild is +# exactly how that binary shipped. Building it alone keeps its zbus on async-io; cargo no-ops this +# when the existing artifact was already resolved that way, and rebuilds it when it wasn't. +echo "==> building punktfunk-tray (release, own invocation — see comment above)" +cargo build --release -p punktfunk-tray --locked STAGE="$(mktemp -d)" trap 'rm -rf "$STAGE"' EXIT diff --git a/packaging/nix/README.md b/packaging/nix/README.md index 22763cc7..bf1848f2 100644 --- a/packaging/nix/README.md +++ b/packaging/nix/README.md @@ -193,7 +193,12 @@ The `${package}/share/punktfunk-host/headless/` helpers (KDE/Sway session script ```sh nix develop # pinned toolchain (rust-toolchain.toml) + all system libs -cargo build --release -p punktfunk-host -p punktfunk-client-linux -p punktfunk-client-session -p punktfunk-tray +cargo build --release -p punktfunk-host -p punktfunk-client-linux -p punktfunk-client-session +# The tray gets its OWN invocation — co-building it with the host unifies the host's +# ashpd -> zbus/tokio onto the tray's zbus (which runs ksni's async-io executor, no tokio runtime), +# and the resulting binary panics at launch: "there is no reactor running, must be called from the +# context of a Tokio 1.x runtime". Same split the .deb / RPM / Arch packaging does. +cargo build --release -p punktfunk-tray ``` The shell exports `PF_FFVK_VULKAN_INCLUDE` (Vulkan headers for pf-ffvk bindgen) and an @@ -218,8 +223,12 @@ The shell exports `PF_FFVK_VULKAN_INCLUDE` (Vulkan headers for pf-ffvk bindgen) host would pull the host's `ashpd → zbus/tokio` onto the tray's shared `zbus`, and the tray then panics at startup (`there is no reactor running, must be called from the context of a Tokio 1.x runtime`). Building it as a separate `-p punktfunk-tray` invocation keeps its `zbus` on async-io; - the host package copies the resulting binary into its `$out`. (The deb/rpm/arch builds co-build the - two in one `cargo build`, so they share this latent crash on Linux — a separate fix.) + the host package copies the resulting binary into its `$out`. (The rpm/arch builds split it the same + way. The **.deb did not**, despite its sibling comments claiming otherwise: `deb.yml` co-built + `-p punktfunk-host -p punktfunk-tray`, and `build-deb.sh`'s own standalone build was skipped because + the poisoned artifact already existed — so this shipped as a real crash-at-launch on Debian/Ubuntu, + not a latent one. Fixed 2026-07-27: the workflow no longer co-builds it and `build-deb.sh` now + rebuilds it unconditionally.) - **The bun packages (`punktfunk-web`, `punktfunk-scripting`) — their `bun install` deps hashes.** Both build their `node_modules` in a *fixed-output derivation* (`bun install` needs the network + the read-public `@unom` npm registry). Each `outputHash` (in `packaging/nix/packages.nix`) is