Skip to content

Ship a native .rpm package for Fedora/RHEL - #77

Merged
timhartmann7 merged 9 commits into
timhartmann7:mainfrom
DevJanderson:feat/linux-rpm-bundle
Aug 18, 2026
Merged

Ship a native .rpm package for Fedora/RHEL#77
timhartmann7 merged 9 commits into
timhartmann7:mainfrom
DevJanderson:feat/linux-rpm-bundle

Conversation

@DevJanderson

Copy link
Copy Markdown
Contributor

Motivation

The black screen reported in #73 / #74 is reproducible and has an identifiable root cause: under Wayland, the WebKit runtime bundled inside the AppImage fails EGL initialization —

Could not create default EGL display: EGL_BAD_PARAMETER. Aborting...

— so the Tauri window opens but the web view never renders. Reproduced on Fedora 44 (GNOME/Wayland, Intel Arc Meteor Lake, Mesa 26.1.6). The same app built against the distro's own webkit2gtk-4.1 renders correctly on the same machine, which points at the AppImage's bundled runtime rather than the app code.

Shipping a native .rpm gives Fedora/RHEL users a package that links the system WebKit (like the .deb already does for Debian/Ubuntu), sidestepping the problem entirely and integrating with the app menu without FUSE.

Changes

  • tauri.conf.json — add rpm to bundle.targets
  • release.yml — build rpm in the existing Linux bundle leg, collect it as OmnySSH-x86_64.rpm, and attach it to the release (SHA256SUMS already covers it via the OmnySSH-* glob; fail_on_unmatched_files: false keeps older re-runs safe)
  • install.sh — prefer the .rpm on dnf-based systems, mirroring the existing .deb branch; AppImage remains the fallback everywhere else
  • README.md — list the .rpm in the download table

No new CI job: Tauri's bundler produces the RPM on the same ubuntu-22.04 runner (it uses a pure-Rust rpm writer, no rpmbuild needed).

Testing

  • Built locally on Fedora 44 with tauri build --bundles rpm; the package declares libwebkit2gtk-4.1.so.0 and libgtk-3.so.0 as dependencies and installs /usr/bin/OmnySSH plus the desktop entry and icons.
  • Installed via dnf install; the app launches and renders correctly (no EGL error in the logs), on the same machine where the v1.1.1 AppImage shows the black screen.
  • sh -n install.sh passes; the workflow YAML parses.

Happy to add a CHANGELOG entry if you'd like it in this PR.

DevJanderson and others added 9 commits August 17, 2026 16:16
The AppImage black-screens on some Wayland setups because its bundled
WebKit runtime fails EGL initialization (EGL_BAD_PARAMETER) — see timhartmann7#73.
A native package linking the distro's own webkit2gtk renders fine on
the same machine.

- add the rpm bundle target to tauri.conf.json
- build, collect, and publish OmnySSH-x86_64.rpm in the release workflow
- prefer the .rpm in install.sh on dnf-based systems, mirroring the
  .deb branch
- list the .rpm in the README download table

Verified on Fedora 44 (Wayland, Intel Arc): the AppImage reproduces the
black screen; the .rpm built from this branch installs and renders
correctly.
The rpm bundler writes Requires: from bundle.linux.rpm.depends and nothing
else — it builds the package with rpm-rs, so rpm's own find-requires never
runs. Without the list dnf installs the package onto a system with no
webview and the app dies at launch on a missing libwebkit2gtk.

Sonames rather than package names: the package that provides them is called
webkit2gtk4.1 on Fedora, libwebkit2gtk-4_1-0 on openSUSE and
lib64webkit2gtk4.1_0 on Mageia, while the capability string is the same
everywhere. The (64bit) suffix is correct for the x86_64 and aarch64 targets
we build.
The webview the AppImage bundles cannot always start hardware rendering on
the host's graphics stack; when it fails the window opens on the dark base
colour and stays blank, with the error going to a terminal nobody launched
the app from.

Twelve seconds after launch, an AppImage whose page never loaded now
re-execs itself once with WEBKIT_DISABLE_DMABUF_RENDERER. The deadline is
its own, well past the three-second reveal, so a slow-but-working start is
never restarted. A marker in the child's environment bounds it to one retry
and doubles as the opt-out.

Guarded three ways so nothing that works today changes: Linux only at
compile time, the running binary must live inside $APPDIR — which rules out
deb and rpm installs, since an AppImage exports $APPDIR to everything it
starts — and a page that loaded is left alone. The environment is set on the
child through Command::env; env::set_var is unsound with threads running.
The rpm branch ended the install on any failure, and install.sh is served
from main while releases are cut from tags — so between merging the rpm
target and the next tag, every dnf host would download a 404 and exit
without a GUI, where it used to get a working AppImage. A dnf host with no
WebKitGTK 4.1 to satisfy the package, such as RHEL 9 and its rebuilds, hits
the same dead end permanently.

Both failures now warn and fall through to the AppImage. The deb and
AppImage branches are unchanged.
Review of the retry turned up four ways it could go wrong quietly:

Nothing tied the retry to the page-load flag that disarms it. Delete that
one store during a refactor of the reveal and every AppImage launch reads
as a failed one, so the app would restart itself into software rendering
every time — with the whole suite still green. The startup contract now
asserts the store, and a const assert pins the heal deadline behind the
reveal instead of a comment saying it should be.

$APPDIR is the string the AppImage runtime exported while current_exe is
the kernel's resolved path, so a symlinked TMPDIR left them uncomparable
and silently disabled the retry; the AppDir is canonicalised first.

WEBKIT_DISABLE_DMABUF_RENDERER=0 means DMABUF stays on, so presence alone
was the wrong test for "the user already chose software rendering" —
WebKit's own check is set and not "0".

exec resets SIGPIPE to SIG_DFL in this process before execvp and does not
restore it when execvp fails, which on a host with no /proc left the
surviving app one closed SSH socket away from dying on a broken pipe.
The rpm fall-through made the dpkg branch reachable on a dnf host for the
first time, and Fedora carries dpkg and apt in its own repositories.
Unpacking a .deb onto an RPM-managed filesystem is worse than the portable
AppImage, so an RPM host now skips it. The warning also stops promising the
AppImage will run — it still needs FUSE and a new enough glibc.
Fedora has no dpkg, so every GUI install there has gone through the AppImage
branch, which writes $INSTALL_DIR/omnyssh and its own omnyssh.desktop. The
package installs /usr/bin/OmnySSH and OmnySSH.desktop — different names, so
nothing was overwritten and the user was left with two identical menu
entries, one of them still launching the build they upgraded to escape.
Only paths this script wrote are removed.
@timhartmann7
timhartmann7 merged commit b985d6f into timhartmann7:main Aug 18, 2026
5 checks passed
@DevJanderson
DevJanderson deleted the feat/linux-rpm-bundle branch August 18, 2026 16:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants