Skip to content

Fix Fleet Desktop not launching on OpenSUSE 16 - #44482

Merged
allenhouchins merged 7 commits into
mainfrom
claude/cranky-hermann-30aede
May 2, 2026
Merged

Fix Fleet Desktop not launching on OpenSUSE 16#44482
allenhouchins merged 7 commits into
mainfrom
claude/cranky-hermann-30aede

Conversation

@allenhouchins

@allenhouchins allenhouchins commented Apr 30, 2026

Copy link
Copy Markdown
Member

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:

  • The -i (login shell) flag is now omitted from the sudo command 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]
  • For all other supported distributions, the previous behavior (using -i) is preserved to maintain compatibility and avoid unnecessary re-testing.

Detection logic:

  • Introduced a new helper function isOpenSUSELeap16Plus in execuser_linux.go to 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 -i

orbit/pkg/execuser/execuser_linux.go

On Linux, Orbit launches Fleet Desktop with:

sudo -n -i -u <user> -H env WAYLAND_DISPLAY=… … FLEET_DESKTOP_DEVICE_IDENTIFIER_PATH=/opt/orbit/identifier … /…/fleet-desktop

The -i flag makes sudo "simulate initial login" — it runs the target user's shell as a login shell and wraps the rest of the command in bash --login -c '<escaped>'. That sources /etc/profile and every script in /etc/profile.d/* before our env KEY=val … fleet-desktop line 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:

FTL missing URL environment FLEET_DESKTOP_DEVICE_IDENTIFIER_PATH

Orbit then respawns it every ~15 s in a tight kill-and-respawn loop, so the tray icon never appears.

Fix: drop -i from the sudo invocation. We don't need a login shell:

  • -H already sets HOME to the target user.
  • sudo's default env_reset sets USER / LOGNAME / SHELL / MAIL and PATH to secure_path.
  • All session vars (WAYLAND_DISPLAY, DISPLAY, DBUS_SESSION_BUS_ADDRESS, LD_LIBRARY_PATH) and every FLEET_DESKTOP_* var are already passed explicitly via env KEY=val ….

After the change, sudo execve()s env directly with no shell layer in between, so /etc/profile.d sourcing and shell-escaping are out of the picture.

The runuser -l /proc/keys-leak regression from PR #32309 does not apply — that was specific to runuser -l creating session keyrings; sudo without -i doesn't.

Checklist for submitter

  • Changes file added: orbit/changes/fleet-desktop-linux-no-login-shell
  • Input data is properly validated; untrusted data interpolated into shell scripts/commands is validated against shell metacharacters.
  • Timeouts are implemented and retries are limited to avoid infinite loops (script's wait loop now bounded at 90s).
  • If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes — N/A.

Testing

Manual QA needed before merge:

  • openSUSE Leap 16 (arm64) — Fleet Desktop process starts, stays running, env vars present, no FTL respawn loop. Done via sudo shim.
  • openSUSE Leap 16 (arm64) — extension fallback — manual tarball install + schema compilation produces a working tray icon (matching what the script automates).
  • Ubuntu 22.04 / 24.04 — regression check: Fleet Desktop tray icon still appears, key-escrow zenity dialog still renders, AppIndicator script still installs via the official path.
  • Fedora (recent) — regression check: same as above.
  • Debian — regression check: same as above.
  • openSUSE Tumbleweed — confirm InstallRemoteExtension path still works (no fallback path triggered).

fleetd/orbit/Fleet Desktop

  • Verified compatibility with the latest released version of Fleet — pure launch-flag change plus a script update; no protocol or schema impact.
  • If the change applies to only one platform, confirmed that runtime.GOOS is used as needed to isolate changes — Go change is in execuser_linux.go, only built on Linux. The script is Linux-only by construction.
  • Verified that fleetd runs on macOS, Linux and Windows — Linux re-verification pending QA above; macOS/Windows code paths unchanged.
  • Verified auto-update works from the released version of component to the new version.

Notes for reviewers

  • The tray-icon visibility issue is an OS-side prerequisite (GNOME 3.26+ has no native tray), so the AppIndicator extension is required regardless. Even after installing it, Wayland requires a logout/login to pick up new extensions — this is documented behavior and not specific to the fallback path.

Summary by CodeRabbit

  • Bug Fixes
    • Resolved Fleet Desktop startup failure on openSUSE Leap 16 by updating system command execution.
    • Enhanced GNOME extension installation process for openSUSE Leap 16+ with improved detection and installation methods.

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

codecov Bot commented Apr 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 26 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.78%. Comparing base (214c00a) to head (6080dbc).
⚠️ Report is 64 commits behind head on main.

Files with missing lines Patch % Lines
orbit/pkg/execuser/execuser_linux.go 0.00% 26 Missing ⚠️
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     
Flag Coverage Δ
backend 68.55% <0.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.
@allenhouchins allenhouchins changed the title Drop sudo -i when launching Fleet Desktop on Linux Fix Fleet Desktop not launching on OpenSUSE 16 Apr 30, 2026
Comment thread orbit/pkg/execuser/execuser_linux.go Outdated

# 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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
@lucasmrod lucasmrod self-assigned this May 1, 2026
Removed the mention of other distributions to focus on openSUSE Leap 16.
@allenhouchins

Copy link
Copy Markdown
Member Author

@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.

Screenshot 2026-04-30 at 10 40 23 PM Screenshot 2026-05-01 at 10 14 44 AM

@lucasmrod lucasmrod left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Smoke tested the changes on Ubuntu 25.04 and Fedora 44 (released 3 days ago).

@allenhouchins
allenhouchins marked this pull request as ready for review May 2, 2026 04:26
@allenhouchins
allenhouchins requested a review from a team as a code owner May 2, 2026 04:26
Copilot AI review requested due to automatic review settings May 2, 2026 04:26

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@allenhouchins
allenhouchins merged commit fa38063 into main May 2, 2026
69 of 71 checks passed
@allenhouchins
allenhouchins deleted the claude/cranky-hermann-30aede branch May 2, 2026 04:26
@coderabbitai

coderabbitai Bot commented May 2, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4eefe9d9-6cf5-4e92-8fa7-de0551662352

📥 Commits

Reviewing files that changed from the base of the PR and between 214c00a and 6080dbc.

📒 Files selected for processing (3)
  • it-and-security/lib/linux/scripts/install-fleet-desktop-required-extension.sh
  • orbit/changes/fleet-desktop-linux-no-login-shell
  • orbit/pkg/execuser/execuser_linux.go

Walkthrough

This 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 -i (login shell) flag from sudo invocations when running on openSUSE Leap 16+, detected by parsing /etc/os-release for ID and VERSION_ID. A new installation script path for Leap 16+ downloads and extracts the GNOME Shell extension directly via tarball instead of using DBus remote installation, with extension enabling handled through gsettings on Leap 16+ and gnome-extensions enable on other distributions. The changes span the user-execution layer and the extension installation tooling across three files.

Possibly related PRs

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/cranky-hermann-30aede

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.

❤️ Share
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 -i on openSUSE Leap 16+ (keep -i elsewhere).
  • 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.

Comment on lines +218 to +252
// 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
}
Comment on lines +178 to +193
// 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"}
}
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.

3 participants