Fix Fleet Desktop not launching on OpenSUSE 16 - #44482
Conversation
sudo -i runs the target user's shell as a login shell and wraps the rest of the command in `bash --login -c '<escaped>'`, sourcing /etc/profile and /etc/profile.d/*. On openSUSE Leap 16, that indirection causes our `env KEY=val ... fleet-desktop` invocation to lose env vars, so fleet-desktop exits with "missing URL environment FLEET_DESKTOP_DEVICE_IDENTIFIER_PATH" and Orbit respawns it every 15s. We don't need a login shell here: -H sets HOME to the target user, sudo's default env_reset sets USER/LOGNAME/SHELL, and all session vars (WAYLAND_DISPLAY, DISPLAY, DBUS_SESSION_BUS_ADDRESS, LD_LIBRARY_PATH) plus FLEET_DESKTOP_* are already passed inline via env. Dropping -i makes sudo execve env directly without a shell layer in between.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #44482 +/- ##
==========================================
+ Coverage 66.76% 66.78% +0.01%
==========================================
Files 2636 2637 +1
Lines 211834 212386 +552
Branches 9388 9388
==========================================
+ Hits 141437 141839 +402
- Misses 57552 57648 +96
- Partials 12845 12899 +54
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
The install-fleet-desktop-required-extension.sh script relies on org.gnome.Shell.Extensions.InstallRemoteExtension, which fetches from extensions.gnome.org. On openSUSE Leap 16 there is no compatible build listed there and the extension never lands, so the original wait loop spins forever. Cap the wait at 90s, and on timeout fall back to fetching the upstream extension tarball directly from GitHub via curl + tar (both present in any Leap 16 / Fedora / Debian base install), extracting into the user's extensions directory, and compiling the gschemas. No new dependency on git, which isn't installed by default on Leap 16.
Removed redundant comment about respawning in a tight loop.
|
|
||
| # Wait until the extension is accepted by the user ("gdbus call" command above is asynchronous). | ||
| while [ ! -d "/home/$username/.local/share/gnome-shell/extensions/$extension_name" ]; do | ||
| # Cap the wait so we don't hang forever if InstallRemoteExtension can't deliver — for |
There was a problem hiding this comment.
I would also try to isolate these changes to run only when detecting that the script is running in OpenSUSE 16+
Detect openSUSE Leap 16+ and apply distro-specific workarounds. In the install script, only cap the InstallRemoteExtension wait and fall back to downloading the extension tarball on openSUSE Leap 16+; other distros keep the indefinite wait behavior. In execuser_linux.go, add isOpenSUSELeap16Plus() and omit sudo -i for Leap 16+ (keep -i for other distros) to avoid losing environment variables under sudo on Leap 16. These changes address failures where extensions.gnome.org lacks a compatible build for Leap 16 and where sudo -i causes fleet-desktop to lose required env vars.
Removed the mention of other distributions to focus on openSUSE Leap 16.
|
@lucasmrod I think this is ready to be reviewed and QA'd. I confirmed everything appears to launch correctly now on OpenSUSE 16 with the fix to orbit and the appindicator install script (see attached screenshots). I could use some help QA'ing the rest though as I did not validate things still work on 15 or other Linux distros. I commented heavily throughout to provide insight into my findings and approach. Feel free to edit the comments to better align with what should be released or let me know if anything else needs addressed.
|
lucasmrod
left a comment
There was a problem hiding this comment.
LGTM!
Smoke tested the changes on Ubuntu 25.04 and Fedora 44 (released 3 days ago).
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.
Tip: disable this comment in your organization's Code Review settings.
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
WalkthroughThis change fixes Fleet Desktop startup failures on openSUSE Leap 16 by modifying how commands are executed as the logged-in user. The core fix removes the Possibly related PRs
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.Comment |
There was a problem hiding this comment.
Pull request overview
This PR fixes Fleet Desktop startup failures on openSUSE Leap 16+ by adjusting how Orbit/scripted tooling launches GUI-user processes so environment variables aren’t lost due to sudo -i (login-shell) behavior on that distro.
Changes:
- Update Linux execuser launch config to omit
sudo -ion openSUSE Leap 16+ (keep-ielsewhere). - Add openSUSE Leap 16+ detection by parsing
/etc/os-release. - Update the GNOME AppIndicator extension install script to handle Leap 16 with a different install/enable flow and add a release note entry.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| orbit/pkg/execuser/execuser_linux.go | Conditionally drops sudo -i on openSUSE Leap 16+ and adds /etc/os-release detection helper. |
| orbit/changes/fleet-desktop-linux-no-login-shell | Notes the user-visible fix for openSUSE Leap 16 startup. |
| it-and-security/lib/linux/scripts/install-fleet-desktop-required-extension.sh | Adjusts sudo invocation and introduces a Leap 16-specific GNOME extension install/enable path. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // isOpenSUSELeap16Plus reports whether the host is running openSUSE Leap 16 or | ||
| // newer. We scope the no-login-shell sudo workaround to that distribution since | ||
| // it is the one observed to break under sudo -i; other distributions retain the | ||
| // previous (login-shell) launch path so we don't have to re-QA them. | ||
| func isOpenSUSELeap16Plus() bool { | ||
| data, err := os.ReadFile("/etc/os-release") | ||
| if err != nil { | ||
| return false | ||
| } | ||
| var id, versionID string | ||
| for line := range strings.SplitSeq(string(data), "\n") { | ||
| key, value, ok := strings.Cut(line, "=") | ||
| if !ok { | ||
| continue | ||
| } | ||
| // /etc/os-release values may be quoted. | ||
| value = strings.Trim(value, `"'`) | ||
| switch key { | ||
| case "ID": | ||
| id = value | ||
| case "VERSION_ID": | ||
| versionID = value | ||
| } | ||
| } | ||
| if id != "opensuse-leap" { | ||
| return false | ||
| } | ||
| // VERSION_ID is typically "16" or "16.0"; compare the major component. | ||
| major, _, _ := strings.Cut(versionID, ".") | ||
| n, err := strconv.Atoi(major) | ||
| if err != nil { | ||
| return false | ||
| } | ||
| return n >= 16 | ||
| } |
| // On openSUSE Leap 16+ we drop -i (login shell). With -i, sudo runs the target | ||
| // user's shell as a login shell and passes the rest of the command via | ||
| // `bash --login -c`, which sources /etc/profile and /etc/profile.d/* and | ||
| // shell-escapes the inline command. On Leap 16 that environment indirection | ||
| // causes our `env KEY=val ... fleet-desktop` invocation to lose env vars, so | ||
| // fleet-desktop exits with "missing URL environment ..." and Orbit respawns it | ||
| // in a tight loop. -H sets HOME to the target user; sudo's default env_reset | ||
| // already sets USER/LOGNAME/SHELL. | ||
| // | ||
| // We keep -i on every other supported distribution to preserve the previously | ||
| // QA'd behavior. | ||
| if isOpenSUSELeap16Plus() { | ||
| args = []string{"-n", "-u", user, "-H"} | ||
| } else { | ||
| args = []string{"-n", "-i", "-u", user, "-H"} | ||
| } |


This pull request addresses a startup issue with Fleet Desktop on openSUSE Leap 16 and similar Linux distributions. The main change is to adjust how Fleet Desktop and key-escrow dialogs are launched to avoid environment variable loss caused by login shell profile scripts. The fix is scoped specifically to openSUSE Leap 16+ to avoid impacting other distributions.
Distribution-specific sudo invocation changes:
-i(login shell) flag is now omitted from thesudocommand when launching Fleet Desktop and key-escrow dialogs on openSUSE Leap 16 and newer, preventing environment variables from being lost due to profile script interference. [1] [2]-i) is preserved to maintain compatibility and avoid unnecessary re-testing.Detection logic:
isOpenSUSELeap16Plusinexecuser_linux.goto detect if the host is running openSUSE Leap 16 or newer by parsing/etc/os-release. This ensures the workaround is only applied where necessary.Related issue: N/A — surfaced via field investigation on openSUSE Leap 16 (arm64).
This PR addresses two distinct issues that together prevent Fleet Desktop from working on openSUSE Leap 16, both validated end-to-end on a real Leap 16 (arm64) host.
1. Launch reliability — drop
sudo -iorbit/pkg/execuser/execuser_linux.goOn Linux, Orbit launches Fleet Desktop with:
The
-iflag makes sudo "simulate initial login" — it runs the target user's shell as a login shell and wraps the rest of the command inbash --login -c '<escaped>'. That sources/etc/profileand every script in/etc/profile.d/*before ourenv KEY=val … fleet-desktopline runs, and shell metacharacters (=,:,/,.) get backslash-escaped through the shell layer.On openSUSE Leap 16 (arm64), that indirection causes the inline env-var assignments to not reach
fleet-desktop, which exits immediately with:Orbit then respawns it every ~15 s in a tight kill-and-respawn loop, so the tray icon never appears.
Fix: drop
-ifrom the sudo invocation. We don't need a login shell:-Halready setsHOMEto the target user.env_resetsetsUSER/LOGNAME/SHELL/MAILandPATHtosecure_path.WAYLAND_DISPLAY,DISPLAY,DBUS_SESSION_BUS_ADDRESS,LD_LIBRARY_PATH) and everyFLEET_DESKTOP_*var are already passed explicitly viaenv KEY=val ….After the change, sudo
execve()senvdirectly with no shell layer in between, so/etc/profile.dsourcing and shell-escaping are out of the picture.The
runuser -l/proc/keys-leak regression from PR #32309 does not apply — that was specific torunuser -lcreating session keyrings; sudo without-idoesn't.Checklist for submitter
orbit/changes/fleet-desktop-linux-no-login-shellTesting
Manual QA needed before merge:
sudoshim.InstallRemoteExtensionpath still works (no fallback path triggered).fleetd/orbit/Fleet Desktop
runtime.GOOSis used as needed to isolate changes — Go change is inexecuser_linux.go, only built on Linux. The script is Linux-only by construction.Notes for reviewers
Summary by CodeRabbit