Skip to content

fix(v3/updater): replace and relaunch the AppImage, not its read-only mount - #6201

Open
AlbinoGeek wants to merge 3 commits into
wailsapp:masterfrom
Rethunk-AI:fix/v3-updater-appimage
Open

AlbinoGeek wants to merge 3 commits into
wailsapp:masterfrom
Rethunk-AI:fix/v3-updater-appimage

Conversation

@AlbinoGeek

@AlbinoGeek AlbinoGeek commented Sep 30, 2026 •

Copy link
Copy Markdown

Description

Inside an AppImage, os.Executable() is the read-only squashfs mount, so the swap and helper spawn targeted an unwritable path that disappears on exit.

When the process runs from $APPDIR, the updater now targets and relaunches $APPIMAGE instead. $APPIMAGE is inherited by child processes, so it is only used when the executable really lives under $APPDIR.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • WEP (proposal only; no implementation)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Added spawn_test.go covering the AppImage and non-AppImage cases.

cd v3 && go test ./pkg/updater/... && go vet ./pkg/updater/... pass on this branch alone; gofmt -l on the changed files is empty.

  • Windows
  • macOS
  • Linux (unit tests only; Fedora Linux 44, amd64, go1.26.x). I did not run a full update end to end on other platforms.

Test Configuration

Fedora Linux 44 Workstation, amd64, GNOME on Wayland. Only the pkg/updater unit tests were run for this change, so no wails doctor output applies.

Checklist:

  • (v2 only) I have updated website/src/pages/changelog.mdx with details of this PR (v3 changelog entries are added automatically)
  • My code follows the general coding style of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

An entry is added to v3/UNRELEASED_CHANGELOG.md and the updater guide is updated.

Overlap with sibling PRs: this is one of three independent updater PRs from the same author (EXDEV staging, AppImage self-path, OnUpdateApplied). Each branch is based on master and passes on its own. They touch the same files in a few places (spawn.go, helper.go, updater.go, the guide, and the changelog), including the small resolveTarget helper that two of them also add, so whichever merges second may need a trivial textual rebase.

The code and this description were written with an AI assistant (Claude). I reviewed the diff and ran the tests listed above.

Summary by CodeRabbit

  • Bug Fixes
    • Fixed AppImage updates to target and relaunch the .AppImage file identified by the APPIMAGE environment variable, rather than attempting to replace read-only mounted contents. This applies when the updater is running from within the AppImage mount.
  • Documentation
    • Clarified that the updater targets the .AppImage file, not the read-only mount, when running inside an AppImage.

Copilot AI balanced review requested due to automatic review settings September 30, 2026 13:13
@github-actions github-actions Bot added Bug Something isn't working v3 Documentation Improvements or additions to documentation labels Sep 30, 2026
@coderabbitai

coderabbitai Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: wailsapp/wails/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 8acea72f-9a64-43f5-8164-fb0dad303c21
📥 Commits

Reviewing files that changed from the base of the PR and between 45d92e8 and bf4260a.

📒 Files selected for processing (1)
  • v3/UNRELEASED_CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • v3/UNRELEASED_CHANGELOG.md

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.


Walkthrough

When the executable runs inside an AppImage mount and the .AppImage file is available, the updater now selects that file as its target. Tests and documentation cover this behavior.

Changes

AppImage target resolution

Layer / File(s) Summary
Resolve and document the updater target
v3/pkg/updater/spawn.go, v3/pkg/updater/spawn_test.go, v3/UNRELEASED_CHANGELOG.md, docs/mpress/content/guides/updater.md
selfExecutable uses appImageOr to select the AppImage file under the specified environment and path conditions. resolveTarget returns its bundle target. Tests cover target selection and resolution. The changelog and guide describe the target behavior.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to bf426

The updater selects the AppImage file for replacement and relaunch under the implemented AppImage conditions. No identified issue prevents merging after normal checks.

Security Architecture Review

Security architecture risk: 🟡 Moderate · up to 0e9c0

The fix targets the correct installed AppImage, but also makes persistent AppImage replacement subject to an existing non-atomic swap procedure. Interruption or competing updates can undermine automatic recovery. No new elevated-privilege or remote attack path was established.

Retained concerns

  • Medium · reliability · inferred: Persistent AppImages newly reach a replacement sequence that removes the installed target before renaming the staged artifact. Helper termination in that interval can leave the installation absent without automatic recovery. Competing helpers also share target.bak without visible target-level serialization. These limitations predate the PR for native executables, but are newly exposed to AppImage installations; returned-error rollback does not cover interruption or coordinate concurrent recovery.
Security review details

Security Blast Radius

  • inferred — The normal affected asset is the installed AppImage and its adjacent backup. Replacement authority is bounded by the helper's operating-system permissions; the inspected Unix launch path sets session detachment, not a credential change. Privileged deployment or cross-tenant exposure was not established.

Security Findings and Attack Paths

  • inferred — A caller controlling APPDIR and APPIMAGE can influence which regular-file path Restart attempts to execute and pass as its replacement target. This is not independently a verified new exploit: successful executable startup is required for handoff, helper mode already accepts environment-selected paths, and no lower-trust environment source crossing into greater authority was established.

Trust Boundaries and Controls

  • observed — The process environment supplies executable identity and the helper protocol. The helper checks target and staged-artifact availability, signals readiness, waits for parent exit, and clears helper-mode variables before replacement or recovery launch. These controls provide lifecycle ordering, not independent target authorization.

Resilience and Maintainability Implications

  • inferred — Automatic recovery depends on the helper remaining alive to execute restoration. Interruption after target removal or interference with the shared backup can defeat that recovery path, even though ordinary returned errors receive bounded retries and rollback.

Hardening Proposals

  • proposed — For regular-file targets, consider same-filesystem staging and atomic replacement, target-scoped serialization, and explicit interrupted-update recovery. Separately document the trusted launcher/environment assumption, especially for deployments that run the application with elevated authority.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 2 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: the updater replaces and relaunches the AppImage file instead of its read-only mount.
Description check ✅ Passed The description explains the bug and fix, identifies the change as a bug fix, reports tests and test environment, and completes the relevant checklist items. It does not link a bug issue, but the temp…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 2 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

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

A rabbit checks the mount at night
Then finds the image file just right
It hops along the target trail
The tests confirm each path detail
And leaves a changelog by the pail

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

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.

Copilot review overview

🟢 Approval recommended

The target resolution is guarded against inherited environment variables and is adequately covered by focused tests.

Review effort: Balanced
Findings: None

What changed in this PR

Fixes AppImage self-updates by targeting the writable AppImage file instead of its temporary read-only mount.

Changes:

  • Resolves $APPIMAGE only when the executable resides under $APPDIR.
  • Adds AppImage and fallback-path tests.
  • Updates updater documentation and changelog.
File Description
v3/​UNRELEASED_CHANGELOG.md Records the AppImage updater fix.
v3/​pkg/​updater/​spawn.go Resolves the correct AppImage update and relaunch target.
v3/​pkg/​updater/​spawn_test.go Tests AppImage detection and fallback cases.
docs/​mpress/​content/​guides/​updater.md Documents AppImage update behavior.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@AlbinoGeek
AlbinoGeek force-pushed the fix/v3-updater-appimage branch from 0e9c059 to d24db08 Compare October 4, 2026 07:13
@taliesin-ai

Copy link
Copy Markdown
Collaborator

Automated v3 GA test run (taliesin-ai) for head ``, run 2026-10-04 against master baseline f21e67fa.

Platform CLI build Unit tests (./pkg/... ./internal/...) Example build (examples/window)
macOS (arm64) PASS PASS (51/51 pkgs) PASS
Windows (amd64) PASS 51/52: internal/webview2/pkg/edge FAIL* PASS
Linux not tested (node offline)

* Same failure on master f21e67fa, so this PR doesn't introduce it. TestCookieManager needs a live WebView2 controller. It times out after 60s in the non-interactive SSH session the runner uses, so this is a test-environment limitation and not a code failure.

The app was not launched (no GUI session over SSH). The Linux-specific paths in this PR were not exercised on Linux. This run doesn't review or approve the PR.

@AlbinoGeek
AlbinoGeek force-pushed the fix/v3-updater-appimage branch from 45d92e8 to bf4260a Compare October 6, 2026 05:57
@AlbinoGeek

Copy link
Copy Markdown
Author

Can I get a human reviewer, or did I make this wrong?

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something isn't working Documentation Improvements or additions to documentation v3

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants